Rails:dependent =>:destroy VS:dependent =>: delete_all

在rails指南中,它是这样描述的:

另外,如果对象与:dependent => :destroy相关联,则会被销毁,如果对象与:dependent => :delete_all相关联,则会被删除

< p >对,酷。但是被摧毁和被删除有什么区别呢?

107847 次浏览

区别在于回调函数。

:delete_all直接在应用程序中创建,并由SQL删除:

DELETE * FROM users where compagny_id = XXXX

使用:destroy,有你所有子元素的实例化。所以,如果你不能销毁它,或者每一个都有自己的:dependent,它的回调函数就可以被调用。

在Rails的模型关联中,你可以指定:dependent选项,它可以采用以下三种形式之一:

  • 关联对象通过调用它们的destroy方法与该对象一起销毁
  • :delete/:delete_all所有关联对象立即销毁,而不调用它们的:destroy方法
  • 所有关联对象的外键都被设置为NULL,而不调用它们的save回调

参见Destroy删除其关联元素,其中Delete_all可以从self表中删除多个数据DELETE * FROM table where field = 'xyz'

:依赖的可能选项:

控制关联对象的所有者被销毁时发生的情况。注意,这些被实现为回调,Rails按顺序执行回调。因此,其他类似的回调可能会影响:依赖行为,而: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'。