如何在Ruby on Rails中保存之前访问验证中的关联表属性

时间:2011-05-31 04:41:46

标签: ruby-on-rails validation nested-attributes

我希望能够跳过验证,如果某个属性设置为false,说状态,问题是此模型有多个嵌套属性,如果status为false,它们也需要跳过验证。

这种植入的目的是,如果一个人想要保存表格条目的草稿,无论出于何种原因,让它进行验证可以停止它们保存它,这不是理想的行为,只需要验证条目通过将状态设置为true来上市。

以下示例

属性状态位于文章

model Article
  has_many :sub_articles
  accepts_nested_attributes_for :sub_articles, :allow_destroy => true

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

model SubArticle
  belongs_to :article
  has_many :foos
  accepts_nested_attributes_for :foos, :allow_destroy => true    

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.status }

model Foo
  belongs_to :sub_article

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article.article.status }

验证跳过文章将起作用,但不会为SubArticle或Foo,因为它们尚未保存,因为没有设置ID,不能使它们能够遍历示例中的关联。

是否可以在验证时访问关联的表属性?

非常感谢任何帮助。

------ ------更新

SubArticle和Foo验证失败的原因是

  

未定义的方法`status'   零:NilClass

这是预料到的,因为验证时间,article_id或sub_article_id仍为零,我已经通过

确认了这一点
model SubArticle
  belongs_to :article
  has_many :foos

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.check_attributes }

def check_attributes
  pp self
end
女巫给出了

#<SubArticle id: nil, body: "", article_id: nil, created_at: nil, updated_at: nil >

-----更新2 ----------

我忘记了重要的细节,模型的所有数据都是使用嵌套表单一次输入的,所以在创建时,所有模型上的所有条目都只在内存中,修复了示例代码所以那会更明显。

3 个答案:

答案 0 :(得分:0)

可以,但您需要使用=>代替=。像这样:

validate_presence_of :body, :unless => Proc.new{|article| !article.status }

有关条件验证的详细信息,请查看:http://guides.rubyonrails.org/active_record_validations_callbacks.html#conditional-validation

答案 1 :(得分:0)

如何有条件地验证ID?

model Article
  has_many :sub_articles

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

    model SubArticle
      belongs_to :article
      has_many :foos

      validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article_id}

model Foo
  belongs_to :sub_article

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article_id }

不确定这是否有效,但如果父模型已保存且因此具有ID,则您基本上只运行验证。但是不适用于更新。也许这个与原始代码之间的混合可以用于更新吗?

答案 2 :(得分:0)

我已经有了它的工作,虽然hack-ish,解决了无法遍历关联,因为ids是nil使用:inverse_of

model Article
  has_many :sub_articles, :inverse_of => :article

  validate_presence_of :body, :unless => Proc.new{|article| !article.status }

model SubArticle
  belongs_to :article, :inverse_of => :sub_articles
  has_many :foos, :inverse_of => :foo

  validate_presence_of :body, :unless => Proc.new{|sub_article| !sub_article.article.status }

model Foo
  belongs_to :sub_article, :inverse_of => :foos

  validate_presence_of :body, :unless => Proc.new{|foo| !foo.sub_article.article.status }

这将使所有图层中正在检查的实例都可以访问status属性。