【发布时间】:2011-02-17 08:20:37
【问题描述】:
在 Rails 指南中是这样描述的:
如果对象与
:dependent => :destroy相关联,则它们将被另外销毁,如果它们与:dependent => :delete_all相关联,则将被删除
好的,很酷。但是被销毁和被删除有什么区别呢? 我都试过了,它似乎做同样的事情。
【问题讨论】:
标签: ruby-on-rails ruby model associations
在 Rails 指南中是这样描述的:
如果对象与
:dependent => :destroy相关联,则它们将被另外销毁,如果它们与:dependent => :delete_all相关联,则将被删除
好的,很酷。但是被销毁和被删除有什么区别呢? 我都试过了,它似乎做同样的事情。
【问题讨论】:
标签: ruby-on-rails ruby model associations
区别在于回调。
:delete_all 直接在您的应用程序中生成并由 SQL 删除:
DELETE * FROM users where compagny_id = XXXX
使用:destroy,您的所有孩子都有一个实例化。所以,如果你不能销毁它或者每个都有自己的:dependent,它的回调可以被调用。
【讨论】:
在 Rails 的模型关联中,您可以指定 :dependent 选项,它可以采用以下三种形式之一:
:destroy/:destroy_all 关联对象通过调用其destroy 方法与此对象一起销毁:delete/:delete_all 所有关联对象都立即销毁,无需调用其:destroy 方法:nullify 所有关联对象的外键都设置为NULL 而不调用它们的save 回调【讨论】:
:restrict。 如果设置为 :restrict,如果该对象有任何关联对象,则不能删除它。
:delete 或:destroy_all 选项? :dependent 选项需要 :destroy、:delete_all、:nullify 或 :restrict (:delete)
:delete 和 :destroy_all 选项不存在。但是,模型上有名为 delete 和 destroy_all 的类方法,因此可能是造成混淆的原因。
参见destroy删除其关联元素,其中delete_all可以从self表中删除多个数据为DELETE * FROM table where field = 'xyz'
:相关的可能选项:
控制关联对象在其所有者被销毁时发生的情况。请注意,这些都是作为回调实现的,Rails 会按顺序执行回调。因此,其他类似的回调可能会影响 :dependent 行为,:dependent 行为可能会影响其他回调。
:destroy 导致所有关联对象也被销毁。
:delete_all 会直接从数据库中删除所有关联的对象(因此不会执行回调)。
:nullify 导致外键设置为 NULL。不执行回调。
:restrict_with_exception 会在有任何关联记录时引发异常。
:restrict_with_error 如果有任何关联对象,则会将错误添加到所有者。
如果与:through 选项一起使用,则连接模型上的关联必须是belongs_to,并且被删除的记录是连接记录,而不是关联记录。
【讨论】:
其实主要区别在于使用:delete_all 时不会调用任何回调。但是当使用 :destroy 时,回调堆栈 (:after_destroy, :after_commit ...) 将被触发。
因此,如果您在要删除的模型中有touch:ing 声明,那么最好使用dependent: :delete_all 而不是'dependent: :destroy'。
【讨论】: