Destroy和Delete之间的区别

时间:2014-03-31 08:58:54

标签: ruby-on-rails destroy delete-row

之间有什么区别

@model.destroy@model.delete

例如:

Model.find_by(col: "foo").destroy_all
//and
Model.find_by(col: "foo").delete_all

如果我使用其中一个真的重要吗?

6 个答案:

答案 0 :(得分:251)

基本上destroy会运行模型上的任何回调,delete不会。

来自Rails API

  • ActiveRecord::Persistence.delete

      

    删除数据库中的记录并冻结此实例以反映不应进行任何更改(因为它们不能保留)。返回冻结的实例。

         

    只需在记录的主键上使用SQL DELETE语句删除该行,并且不会执行任何回调。

         

    要强制执行对象的before_destroy和after_destroy回调或任何:依赖关联选项,请使用#destroy。

  • ActiveRecord::Persistence.destroy

      

    删除数据库中的记录并冻结此实例以反映不应进行任何更改(因为它们不能保留)。

         

    有一系列与destroy相关的回调。如果before_destroy回调返回false,则取消操作并且destroy返回false。有关详细信息,请参阅ActiveRecord :: Callbacks。

答案 1 :(得分:87)

delete将仅从db中删除当前对象记录,但不从db。

中删除其关联的子记录

destroy将从db中删除当前对象记录,并从db。

中删除其关联的子记录

他们的使用非常重要:

如果多个父对象共享公共子对象,则在特定父对象上调用destroy将删除在其他多个父对象之间共享的子对象。

答案 2 :(得分:11)

当您在destroy对象上调用destroy_allActiveRecord时,ActiveRecord'销毁'进程启动后,它会分析您要删除的类,它确定它应该对依赖项执行的操作,运行验证等等。

当您在对象上调用deletedelete_all时,ActiveRecord仅尝试针对数据库运行DELETE FROM tablename WHERE conditions查询,不执行其他ActiveRecord - 等级任务。

答案 3 :(得分:4)

是的,这两种方法之间存在重大差异 如果希望快速删除记录而不调用模型回调,请使用delete_all

如果您关心模型回调,请使用destroy_all

来自官方文档

http://apidock.com/rails/ActiveRecord/Base/destroy_all/class

  

destroy_all(conditions = nil)public

     

通过实例化每条记录来销毁记录匹配条件   并调用其destroy方法。执行每个对象的回调   (包括:依赖关联选项和   before_destroy / after_destroy Observer方法)。返回集合   被摧毁的物体;每个都将被冻结,以反映这一点   不应该做任何改变(因为它们不能被保留)。

     

注意:每个记录的实例化,回调执行和删除   一次删除多条记录时可能会非常耗时。它   每条记录至少生成一个SQL DELETE查询(或者更多,   强制执行你的回调)。如果要快速删除多行,   如果不关心它们的关联或回调,请使用delete_all   代替。

答案 4 :(得分:2)

基本上"删除"直接向数据库发送查询以删除记录。在这种情况下,Rails不知道它正在删除的记录中有哪些属性,也没有任何回调(例如before_destroy)。

"销毁"获取传递的id,使用" find"从数据库中获取模型。方法,然后调用destroy。这意味着会触发回调。

你会想要使用"删除"如果您不希望触发回调,或者您希望获得更好的性能。否则(大多数时候)你会想要使用" destroy"。

答案 5 :(得分:0)

已经有很多答案;想继续前进。

docs

  

对于has_many,destroy和destroy_all将始终调用要删除的记录的destroy方法,以便运行回调。但是delete和delete_all将根据:depend选项指定的策略进行删除,或者,如果未给出:dependent选项,则它将遵循默认策略。除了has_many:through以外,默认策略是不执行任何操作(保留设置了父ID的外键),默认策略是delete_all(删除联接记录,而不运行其回调)。

deleteActiveRecord::Association.has_many的用法分别不同。对于后者,删除将执行ActiveRecord::Base并绕过所有验证/回调。前者将根据传递给关联的SQL DELETE选项执行。但是,在测试期间,我发现以下副作用,其中仅针对:dependent而不是delete

运行回调

delete_all示例:

dependent: :destroy