Rails:depend =>:destroy VS:depend =>:delete_all


192

在导轨中的描述如下:

如果对象与关联,则将另外销毁;如果与关联:dependent => :destroy,则将其删除。:dependent => :delete_all

是的,很酷。但是被销毁和被删除有什么区别?我都尝试过,似乎做同样的事情。

Answers:


200

区别在于回调。

:delete_all直接在您的应用程序,并通过SQL删除:

DELETE * FROM users where compagny_id = XXXX

使用:destroy,您所有孩子的实例化。因此,如果您无法销毁它,或者它们每个都有自己的:dependent,则可以调用其回调。


83
如果您有很多子代(如果有很多子代,则n ^ 2;如果有很多子代,依此类推),对每个子代对象的实例化和对destroy的调用将很慢。delete_all是一种“从轨道上删除它”的解决方案,您无需关心/在模型上销毁回调之前/之后没有任何内容。
Ryan Bigg

131

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

  • :destroy/:destroy_all通过调用其destroy方法将关联对象与此对象一起销毁
  • :delete/:delete_all所有关联的对象将立即销毁,而无需调用其:destroy方法
  • :nullify所有关联对象的外键都设置为NULL不调用其save回调


21
从Rails 3.0开始,也可以指定:restrict如果设置为:restrict,则如果该对象具有任何关联的对象,则无法删除。
RocketR 2011年

17
从外观上看没有:delete:destroy_all选择吗?:depend选项期望:destroy,:delete_all,:nullify或:restrict(:delete)
Mike Campbell

2
@MikeCampbell,:delete并且:destroy_all选项不存在。但是,在模型上有被调用的类方法deletedestroy_all因此这可能是造成混淆的原因。
berezovskyi 2014年

@MikeCampbell您缺少更多的选项,请参阅:depend选项必须是[:destroy,:delete_all,:nullify,:restrict_with_error,:restrict_with_exception]中的一种
Pravin Mishra 2014年

30

请参阅destroy删除其关联的元素 ,其中delete_all可以从self表中删除多个数据,如下所示DELETE * FROM table where field = 'xyz'

:取决于可能的选项:

控制销毁所有者时关联对象发生的情况。请注意,这些被实现为回调,并且Rails按顺序执行回调。因此,其他类似的回调可能会影响:depend行为,并且该:dependent行为可能会影响其他回调。

:destroy 导致所有关联的对象也被破坏。

:delete_all 使所有关联的对象直接从数据库中删除(因此将不执行回调)。

:nullify导致将外键设置为NULL。不执行回调。

:restrict_with_exception 如果存在任何关联的记录,则会引发异常。

:restrict_with_error 如果存在任何关联的对象,则会导致将错误添加到所有者。

如果与该:through选项一起使用,则联接模型上的关联必须是belongs_to,并且被删除的记录是联接记录,而不是关联的记录。


3

实际上,主要区别在于:delete_all使用时不会调用任何回调。但是,使用时,将触发:destroy回调堆栈(:after_destroy:after_commit...)。

因此,如果touch:在删除的模型中有ing声明,则最好使用dependent: :delete_all“ Dependent :: destroy”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.