Проверка ActiveRecord по родительскому атрибуту - PullRequest
3 голосов
/ 13 января 2011

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

  def draft?
    raise self.article.draft
  end

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

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

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

ОБНОВЛЕНИЕ

Я пытался так:

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

И это выглядит как грязно-грязный хак тоже

1 Ответ

2 голосов
/ 13 января 2011

Это частый случай использования конечного автомата. Для этого есть несколько плагинов rails.

http://ruby -toolbox.com / категории / state_machines.html

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

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

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

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

Попробуйте with_options.

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 сделает в любом случае.

...