【发布时间】:2009-12-16 15:08:04
【问题描述】:
通过多次测试迭代,我刚刚注意到,当这些模型的实例被删除时,表示两个模型之间的 HABTM 关系的连接表并没有删除条目。删除具有 HABTM 关系的模型实例时,我需要做一些特殊的事情吗?
【问题讨论】:
标签: mysql ruby-on-rails has-and-belongs-to-many relationships dependent-destroy
通过多次测试迭代,我刚刚注意到,当这些模型的实例被删除时,表示两个模型之间的 HABTM 关系的连接表并没有删除条目。删除具有 HABTM 关系的模型实例时,我需要做一些特殊的事情吗?
【问题讨论】:
标签: mysql ruby-on-rails has-and-belongs-to-many relationships dependent-destroy
仔细检查后,HABTM 关系应该会删除连接表条目。但是,当您使用 delete 方法消除记录时,HABTM 关系或我在此解决方案的原始版本(参见帖子历史记录)中描述的关系都不会删除这些连接表条目。 ActiveRecord::Base#delete 不会触发任何回调,例如 HABTM 关系为从连接表中删除孤立条目而建立的回调。相反,您应该使用ActiveRecord::Base#destroy。
您必须使用原始 SQL 来删除不需要的条目。如果您决定创建连接模型,则可以遍历连接模型中的条目,删除没有关联的条目。
例子:
class Foo < ActiveRecord::Base
has_many :foo_bars, :dependent => :destroy
has_many :bars, :through => :foo_bars
end
class FooBar < ActiveRecord::Base
belongs_to :foo
belongs_to :bar
end
class Bar < ActiveRecord::Base
has_many :foo_bars, :dependent => :destroy
has_many :foos, :through => :foo_bars
end
FooBar.all.each{|fb| fb.destroy? if fb.foo.nil? || fb.bar.nil? }
【讨论】:
FooBar.all.each{ ... } 只是为了摆脱连接表中的孤立记录。移动到 has_many :though 关系与标记为 :dependent => :destroy 的连接模型关联后,如果删除它们所属的记录,则不会孤立连接表中的记录。添加 :dependent => :destroy 选项将销毁与您正在销毁的记录相关的所有关联记录。但是,它不会在删除时触发。您应该阅读有关 ActiveRecord::Base#destroy、ActiveRecord::Base#delete 和 ActiveRecord::Associations::ClassMethods 的文档。
连接表中的条目应该会被删除,而无需您做任何特别的事情。如果您遇到奇怪的情况,您可以将:delete_sql 选项添加到您的代码中以更改行为。删除连接另一端的对象不是默认行为。
【讨论】: