之间有什么区别
@model.destroy
和@model.delete
例如:
Model.find_by(col: "foo").destroy_all
//and
Model.find_by(col: "foo").delete_all
如果我使用其中一个真的重要吗?
答案 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_all
或ActiveRecord
时,ActiveRecord
'销毁'进程启动后,它会分析您要删除的类,它确定它应该对依赖项执行的操作,运行验证等等。
当您在对象上调用delete
或delete_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(删除联接记录,而不运行其回调)。
delete
和ActiveRecord::Association.has_many
的用法分别不同。对于后者,删除将执行ActiveRecord::Base
并绕过所有验证/回调。前者将根据传递给关联的SQL DELETE
选项执行。但是,在测试期间,我发现以下副作用,其中仅针对:dependent
而不是delete
delete_all
示例:
dependent: :destroy