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
选项不存在。但是,模型上有名为 delete
和 destroy_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 中的 require、require_dependency 和常量重载有啥关系?
Rails 3.1 引擎:my_engine.gemspec、add_dependency、add_development_dependency 和 Gemfile 的区别