Rails多态依赖:: destroy无法正常工作

时间:2014-06-11 23:11:34

标签: 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

让我们说我的应用程序可以将鼻屎从手指转移到组织上,一旦完成,手指就会被摧毁(哎呀!)。出于某种原因,当手指被摧毁时,它也会破坏先前属于它的鼻屎并且因此被转移到组织中。在日志中我可以看到,当手指被摧毁时,它会记住用于属于它的鼻屎的ID并将其销毁。它没有检查以确保boogerable_type仍然是手指'从而摧毁那些带有'组织的人。

当手指被摧毁时,它正在这样做:

DELETE FROM boogers WHERE booger.id = 387

应该这样做:

DELETE FROM boogers WHERE boogerable_id = 1 AND boogerable_type = 'finger'

之前有人遇到过这个问题吗?

1 个答案:

答案 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销毁手指?