Bre*_*her 15 ruby-on-rails-3 ruby-on-rails-4
假设我有三个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
Run Code Online (Sandbox Code Playgroud)
假设我的应用程序可以将鼻屎从手指转移到组织上,一旦完成,手指就会被摧毁(哎呀!).出于某种原因,当手指被摧毁时,它也会破坏先前属于它的鼻屎并且因此被转移到组织中.在日志中我可以看到,当手指被摧毁时,它会记住用于属于它的鼻屎的ID并将其销毁.它不会检查以确保boogerable_type仍然是"手指",因此会破坏类型为"组织"的那些.
当手指被摧毁时,它正在这样做:
DELETE FROM boogers WHERE booger.id = 387
Run Code Online (Sandbox Code Playgroud)
什么时候应该这样做:
DELETE FROM boogers WHERE boogerable_id = 1 AND boogerable_type = 'finger'
Run Code Online (Sandbox Code Playgroud)
有没有人遇到过这个?
首先,您需要知道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
Run Code Online (Sandbox Code Playgroud)
该dependent: :destroy语句意味着当destroy被调用时f,它也将被调用与之关联的所有鼻屎f.并且由于f它的booger被加载到内存中,该f.booger[0]对象仍然存在于f.boogers其中包含每个元素的数组中,包括boogers[0]在f被销毁时被销毁.
这种情况的解决方案是在调用之前点击f.boogers.reload更新数组.f.destroy
此外,请注意,当你销毁时f,所有相关的boogers也将被destroy编辑,这真的是你想要的吗?boogers当其中一个被转移到别的东西时,用剩下的所有关联来摧毁手指?