在嵌套表單中,我希望用戶能夠同時創建或修改所有Parent
的Childs
。因此,讓我們使傳遞的PARAMS是這樣的:Rails如何驗證跨嵌套子對象的唯一性
{"childs_attributes" => [{attribute:1}, {attribute:2}, {attribute:3}...]}
我想驗證,對於任何一個Parent
稱,attribute
一切都其Childs
必須是唯一的。換句話說,在上面的例子中,這是可以的,因爲你會得到:
Parent.childs.pluck(:attribute).uniq.length == Parent.childs.pluck(:attribute).length
但是,如果PARAMS傳遞就像下面,這將會是驗證規則的違反:
{"childs_attributes" => [{attribute:1}, {attribute:2}, {attribute:3}...]}
到目前爲止,我已經想出來做這個驗證的唯一解決方案是在Controller中......我知道這是不好的做法,因爲我們想把它推到模型上。
的問題是,如果在模型中我有類似下面:
class Parent
validate :unique_attribute_on_child
def unique_attribute_on_child
attribute_list = self.childs.pluck(:attribute)
if attribute_list.uniq.length != attribute_list.length
errors[:base] << "Parent contains Child(s) with same Attribute"
end
end
end
這是行不通的,因爲self.childs.pluck(:attribute)
不會返回在當前的更新通過attribute
,因爲當前的更新拿下還沒有儲蓄。
我想我可以做一些類似於after_save
的東西,但是這感覺真的很複雜,因爲它回溯並顛倒了數據庫提交(更不用說,下面寫的代碼[未經測試,只是一個例子]可能導致循環循環如果我不小心,因爲父驗證關聯的孩子)
after_save :unique_attribute_on_child
def unique_attribute_on_child
attribute_list = self.childs.pluck(:attribute)
if attribute_list.uniq.length != attribute_list.length
self.childs.each { |c| c.update_attributes(attribute:nil) }
errors[:base] << "Parent contains Child(s) with same Attribute"
end
end
end
其他想法?