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

Posted

技术标签:

【中文标题】Rails :dependent => :destroy VS :dependent => :delete_all【英文标题】: 【发布时间】:2011-02-17 08:20:37 【问题描述】:

在 Rails 指南中是这样描述的:

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

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

【问题讨论】:

【参考方案1】:

区别在于回调。

:delete_all 直接在您的应用程序中生成并由 SQL 删除:

DELETE * FROM users where compagny_id = XXXX

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

【讨论】:

如果你有很多孩子(如果你有孙子,n^2,依此类推),每个孩子对象的实例化和销毁调用会很慢。 delete_all 是一种“从轨道上核对它”的解决方案,您不关心/在模型上销毁回调之前/之后没有任何。【参考方案2】:

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

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

【讨论】:

参见api.rubyonrails.org/classes/ActiveRecord/Associations/…(搜索“nullify”)以获取权威的 rdocs。 从 Rails 3.0 开始,也可以指定:restrict如果设置为 :restrict,如果该对象有任何关联对象,则不能删除它。 看起来没有:delete:destroy_all 选项? :dependent 选项需要 :destroy、:delete_all、:nullify 或 :restrict (:delete) @MikeCampbell、:delete:destroy_all 选项不存在。但是,模型上有名为 deletedestroy_all 的类方法,因此可能是造成混淆的原因。 @MikeCampbell 您缺少更多选项,请参阅 :dependent 选项必须是 [:destroy, :delete_all, :nullify, :restrict_with_error, :restrict_with_exception] 之一]【参考方案3】:

参见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,并且被删除的记录是连接记录,而不是关联记录。

【讨论】:

【参考方案4】:

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

因此,如果您在要删除的模型中有touch:ing 声明,那么最好使用dependent: :delete_all 而不是'dependent: :destroy'。

【讨论】:

以上是关于Rails :dependent => :destroy VS :dependent => :delete_all的主要内容,如果未能解决你的问题,请参考以下文章

rails dependent

Rails 销毁所有嵌套关联

Rails 照片、用户、评论

Rails 中的 require、require_dependency 和常量重载有啥关系?

Rails 3.1 引擎:my_engine.gemspec、add_dependency、add_development_dependency 和 Gemfile 的区别

使用dependent: :destroy 在rails 上不起作用