我有两个不同的对象,可以属于一个父对象。这些子对象也可以彼此属于(多对多)。确保彼此属于的子对象也属于同一父对象的最佳方法是什么。
作为我正在尝试做的一个示例,我有一个Kingdom
,其中包含许多People
和Land
。 People
模型会有一个自定义validate
,如果有Land
不匹配,我会检查每个相关的error.add
和kingdom_id
。 Land
模型具有类似的validate
。
这似乎有效,但在更新时允许记录保存'THIS IS AN ERROR'
错误在people.errors
,但是引发错误的Land
已添加到{{ 1}}集合。
People
理想情况下,我希望错误取消记录更新。我还有另一种方法可以解决这个问题,还是我完全走错了方向?
kingdom = Kingdom.create
people = People.create(:kingdom => kingdom)
land = Land.create(:kingdom_id => 999)
people.lands << land
people.save
puts people.errors.inspect # @messages={:base=>["THIS IS AN ERROR"]
puts people.lands.inspect # [#<Land id: 1...
答案 0 :(得分:2)
首先,验证不会阻止将记录添加到模型的未加载集合中。它将阻止修订后的集合持久存储到数据库中。因此模型将处于无效状态,并以适当的错误进行标记。要查看此内容,您只需重新加载people
对象。
您的逻辑中也有错误 - 即使找不到无效的kingdom_id,kingdom_match
方法也永远不会返回true。你应该添加一行来解决这个问题:
def kingdom_match
self.lands.each do |l|
return false if l.kingdom_id != self.kingdom_id
end
true
end
您可以使此验证更简洁,并完全跳过kingdom_match
方法:
def same_kingdom?
if self.lands.any?{|l| l.kingdom_id != self.kingdom_id }
errors.add(:base, 'THIS IS AN ERROR')
end
end