何时使用“validates_associated”v。“belongs_to:parent,:validate => true”

似乎在rails中你可以在两个地方定义关联validation,或者在关联本身上:

class Child belongs_to :parent, :validate => true end 

或者作为validation回调:

 class Child belongs_to :parent validates_associated :parent end 

这两种方法有什么区别?

测试差异

我想也许前者会产生背压并强制父母只有在孩子有效的情况下才有效:

即(设置时:validate => true)

 child.valid? # => false child.parent.valid? # => also evaluates to false because of the :validate => true condition # do whatever it takes to make the child valid again #... child.valid? # => true child.parent.valid? # => true 

但是我测试了它,但这不会发生。 那两种方法之间有什么区别(如果有的话)?

我不得不深入研究Rails(3.0.7)代码以找到一些差异。 核心function对我来说看起来一样 – 他们似乎都认为valid? 在相关记录上。

我发现的主要区别仅在使用:autosavefunction时或者在销毁关联对象或将其标记为销毁时出现。 例如,我有:

 class AbsentDate < ActiveRecord::Base belongs_to :user, :autosave => true, :validate => true end 

我看到以下行为:

 user = User.new(:username => "Jimmy") user.valid? # => true ad = AbsentDate.new(:user => user) user.username = nil user.valid? # => false ad.valid? # => false ad.errors.full_messages # => ["User username cannot be empty"] ad.user.mark_for_destruction ad.valid? # => true 

请注意,标记用户进行销毁会导致有效的AbsentDate。 另请注意,只有一条错误消息。 现在考虑这种情况:

 class AbsentDate < ActiveRecord::Base belongs_to :user, :autosave => true validates_associated :user end 

这就是我看到的情况:

 user = User.new(:username => "Jimmy") user.valid? # => true ad = AbsentDate.new(:user => user) user.username = nil user.valid? # => false ad.valid? # => false ad.errors.full_messages # => ["User username cannot be empty", "User is invalid"] ad.user.mark_for_destruction ad.valid? # => false 

这次有两条错误消息,即使其用户已被标记为销毁,AbsentDate仍然是假的。 我能够通过调用destroy而不是mark_for_destruction来复制这些结果。

最后一件事:如果你使用validates_associated ,你会得到几个选项( :if:unless:on:message ),如果你使用belongs_to上的标志,你将不会拥有这些选项。