假设我有三个Active Record模型:
class Tissue
has_many :boogers, as: :boogerable, dependent: :destroy
end
class Finger
has_many :boogers, as: :boogerable, dependent: :destroy
end
Class Boogers
belongs_to :boogerable, polymorphic: true
end
让我们说我的应用程序可以将鼻屎从手指转移到组织上,一旦完成,手指就会被摧毁(哎呀!)。出于某种原因,当手指被摧毁时,它也会破坏先前属于它的鼻屎并且因此被转移到组织中。在日志中我可以看到,当手指被摧毁时,它会记住用于属于它的鼻屎的ID并将其销毁。它没有检查以确保boogerable_type仍然是手指'从而摧毁那些带有'组织的人。
当手指被摧毁时,它正在这样做:
DELETE FROM boogers WHERE booger.id = 387
应该这样做:
DELETE FROM boogers WHERE boogerable_id = 1 AND boogerable_type = 'finger'
之前有人遇到过这个问题吗?
答案 0 :(得分:8)
首先,您需要知道ActiveRecord destroy
方法在需要销毁它时使用对象的:id
字段。并且dependent: :destroy
选项将在与当前对象相关的所有对象上触发destroy
方法。
我认为你正在做这样的事情:
f = Finger.find(finger_id)
t = Tissue.find(tissue_id)
f.boogers[0].boogerable = t
f.boogers[0].save!
f.destroy
dependent: :destroy
语句表示在destroy
上调用f
时,也会调用与f
相关联的所有鼻屎。由于f
及其booger被加载到内存中,f.booger[0]
对象仍然存在于f.boogers
数组中,其中包含boogers[0]
的每个元素都会被销毁f
被摧毁。
此案例的解决方案是,在调用f.boogers.reload
之前,您点击f.destroy
更新数组。
此外,请注意,当您销毁f
时,所有关联的boogers
也将destroy
,这真的是您想要的吗?当其中一个被转移到别的东西时,用剩下的所有关联boogers
销毁手指?