2011-01-13 3 views
3

У меня есть модель, например, статья. Статья has_one ArticleContent. ArticleContent по умолчанию проверяет все свои атрибуты. Но мне нужна дополнительная функциональность - чтобы сохранить проект статьи без какой-либо проверки. Итак, я передаю: draft => false как один из параметров в Article.new(), затем я делаю @ article.build_article_content(). В ArticleContent есть некорректный код:Проверка ActiveRecord по атрибуту родителя

def draft? 
    raise self.article.draft 
    end 

    validates_presence_of :header, :message => "We have no fuckin' header!", :unless => :draft? 

Конечно, это не работает. В момент проекта? исполнения нет никакого подходящего объекта статьи в любом месте, поэтому self.article возвращает nil. Хорошая попытка, codemonkey ...

У кого-нибудь есть сладкие идеи? Я думаю, чтобы сделать @ content.save! это не очень хорошая идея

UPDATE

Я попробовал так:

def draft 
    self[:draft] 
end 

def draft=(value) 
    self[:draft] = value 
end 

def draft? 
    self[:draft] 
end 

validates_presence_of :field1, :message => "msg1", :unless => :draft? 
validates_presence_of :field2, :message => "msg2", :unless => :draft? 
validates_presence_of :field3, :message => "msg3", :unless => :draft? 

Это работает, но как я могу это группа?

unless self.draft? 
    validates_presence_of :field1, :message => "msg1" 
    validates_presence_of :field2, :message => "msg2" 
    validates_presence_of :field3, :message => "msg3" 
end 

Говорит, что проект? метод не найден. Также я должен делать

@article.content.draft = @article.draft 

И это выглядит грязно-грязный хак слишком

+0

Извините, я только что видел ваше обновление. – noodl

ответ

2

Это общий случай использования для государственной машины. Для них предусмотрено несколько плагинов rails.

http://ruby-toolbox.com/categories/state_machines.html

Если вам не нужна полная реализация государственной машины она все еще может быть полезно иметь государственный столбец в вашей модели ArticleContent. Его значениями будут «новый», «черновик», «опубликованный» и т. Д. Ваш валидация будет смотреть на значение этого столбца при принятии решения о том, что делать, как:

validates :content, :presence => true, :unless => Proc.new { |a| a.state == "Draft" } 

(я уверен, что это не правильный синтаксис, но вы должны получить то, что я стремлюсь в.)

Чтобы ответить на ваше ОБНОВЛЕНИЕ

Попробуйте с помощью_объектов.

with_options :unless => :draft? do |o| 
    o.validates_presence_of :field1, :message => "msg1" 
    o.validates_presence_of :field2, :message => "msg2" 
    o.validates_presence_of :field3, :message => "msg3" 
end 

Глядя на ваш код, есть пара запахов. Для того, чтобы опрокинуть валидацию, нужно сделать следующее: errors.add(blah), а не поднимать исключение. Кроме того, ваши методы, определенные для доступа к столбцу проекта, выглядят немного избыточными. Они просто делают то, что AR будет делать в любом случае.

Смежные вопросы