ruby-on-rails - guides - rails分類



何時使用“validates_associated”v。“belongs_to:parent,:validate=> true” (1)

似乎在rails中你可以在兩個地方定義關聯驗證,或者在關聯本身上:

class Child

  belongs_to :parent, :validate => true

end

或者作為驗證回調:

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

但是我測試了它,但這不會發生。 那兩種方法之間有什麼區別(如果有的話)?

https://src-bin.com


Answer #1

我不得不深入研究Rails(3.0.7)代碼以找到一些差異。 核心功能對我來說看起來一樣 - 他們似乎都認為valid? 在相關記錄上。

我發現的主要區別僅在使用:autosave功能時或者在銷毀關聯對像或將其標記為銷毀時出現。 例如,我有:

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上的標誌,你將不會擁有這些選項。