爲了驗證嵌套屬性在我的Rails應用程序中工作幾個小時,我很掙扎。需要注意的一點是,我必須根據父級的屬性動態驗證嵌套屬性,因爲根據父級進程中的位置,所需信息的數量隨時間而變化。Rails的accept_nested_attributes_for對交易對象進行驗證
因此,這裏是我的設置:我有一個父與許多不同的關聯模型,我想驗證隨後嵌套的屬性,每次我保存父。鑑於驗證動態變化,我不得不寫在模型中定義驗證方法:
class Parent < ActiveRecord::Base
attr_accessible :children_attributes, :status
has_many :children
accepts_nested_attributes_for :children
validate :validate_nested_attributes
def validate_nested_attributes
children.each do |child|
child.descriptions.each do |description|
errors.add(:base, "Child description value cant be blank") if description.value.blank? && parent.status == 'validate_children'
end
end
end
end
class Child < ActiveRecord::Base
attr_accessible :descriptions_attributes, :status
has_many :descriptions
belongs_to :parent
accepts_nested_attributes_for :descriptions
end
在我的控制器時我要救我呼籲家長update_attributes方法。現在的問題是,顯然,rails會針對數據庫運行驗證,而不是針對用戶或控制器修改的對象。因此,可能發生的情況是,用戶刪除了孩子的值,並且驗證將通過,而後來的驗證將不會通過,因爲數據庫中的項無效。
下面是這種情況的一個簡單的例子:
parent = Parent.create({:status => 'validate_children', :children_attributes => {0 => {:descriptions_attributes => { 0 => {:value => 'Not blank!'}}}})
#true
parent.update_attributes({:children_attributes => {0 => {:descriptions_attributes => { 0 => {:value => nil}}}})
#true!!/since child.value.blank? reads the database and returns false
parent.update_attributes({:children_attributes => {0 => {:descriptions_attributes => { 0 => {:value => 'Not blank!'}}}})
#false, same reason as above
驗證適用於一級協會,例如如果一個Child有一個'value'屬性,我可以按照我的方式運行驗證。問題在於深度關聯顯然無法在保存之前進行驗證。
任何人都可以指出我如何解決這個問題的正確方向?我目前看到的唯一方法是保存記錄,事後驗證它們,並在驗證失敗時刪除/恢復它們,但我誠實地希望有更清潔的東西。
謝謝大家提前!
SOLUTION
因此,原來我是通過直接在定製驗證引用那些運行於深嵌套模型的驗證,這種方式:
class Parent < ActiveRecord::Base
[...]
has_many :descriptions, :through => :children
[...]
def validate_nested_attributes
descriptions.each do |description|
[...]
end
end
end
由於某種原因導致的問題我在上面。感謝Santosh測試我的示例代碼並報告它正在工作,這指出我在正確的方向弄清楚了這一點。
爲了將來的參考,原始問題中的代碼適用於這種動態的,深度嵌套的驗證。
有在你的代碼一些錯誤。它可能是錯字。 1.「兒童價值不能爲空」 - 單引號內的單引號。 2. && parent.status ='validate_children' - 這不是比較。它的任務 – 2013-04-23 11:21:22
抱歉錯別字!這裏的代碼只是我的應用程序的一個簡化的例子,所以這不是它不工作的原因,但感謝指出:) – 2013-04-23 11:39:03