Answers:
基本上destroy
在模型上运行任何回调,而delete
没有。
ActiveRecord::Persistence.delete
删除数据库中的记录并冻结该实例以反映不应进行任何更改(因为它们不能持久保存)。返回冻结的实例。
只需在记录的主键上使用SQL DELETE语句删除该行,就不会执行回调。
要强制执行对象的before_destroy和after_destroy回调或任何:dependent关联选项,请使用#destroy。
ActiveRecord::Persistence.destroy
删除数据库中的记录并冻结该实例以反映不应进行任何更改(因为它们不能持久保存)。
有一系列与destroy相关的回调。如果before_destroy回调返回false,则取消操作,destroy返回false。有关更多详细信息,请参见ActiveRecord :: Callbacks。
model#before_destroy
可以用来destroy()
在某些条件下终止最终调用的。
delete
只会从db中删除当前对象记录,而不会从db中删除其相关的子记录。
destroy
将从db中删除当前对象记录,并从db中删除其相关的子记录。
它们的使用确实很重要:
如果您的多个父对象共享公共子对象,则调用destroy
特定父对象将删除在其他多个父对象之间共享的子对象。
destroy
是后代,而不是子代:根据文档,destroy“根据属性创建一个新对象,然后在其上调用destroy”。rubydoc.info/docs/rails/4.1.7/ActiveRecord%2FRelation:destroy
是的,这两种方法之间存在主要差异。如果要快速删除记录而不调用模型回调,请使用delete_all
如果您关心模型回调,请使用destroy_all
来自官方文档
http://apidock.com/rails/ActiveRecord/Base/destroy_all/class
destroy_all(conditions = nil)公共
通过实例化每个记录并调用其destroy方法来销毁匹配条件的记录。每个对象的回调都被执行(包括:dependent关联选项和before_destroy / after_destroy Observer方法)。返回被破坏的对象的集合;每个都将被冻结,以反映不应进行任何更改(因为它们无法持久保存)。
注意:一次删除许多记录时,实例化,回调执行和删除每个记录可能很耗时。它每条记录至少生成一个SQL DELETE查询(或者可能更多,以强制执行回调)。如果要快速删除许多行,而不用担心它们的关联或回调,请使用delete_all。
已经有很多答案;想多跳一点。
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
例:
class Parent < ApplicationRecord
has_many :children,
before_remove: -> (_) { puts "before_remove callback" },
dependent: :destroy
end
class Child < ApplicationRecord
belongs_to :parent
before_destroy -> { puts "before_destroy callback" }
end
> child.delete # Ran without callbacks
Child Destroy (99.6ms) DELETE FROM "children" WHERE "children"."id" = $1 [["id", 21]]
> parent.children.delete(other_child) # Ran with callbacks
before_remove callback
before_destroy callback
Child Destroy (0.4ms) DELETE FROM "children" WHERE "children"."id" = $1 [["id", 22]]
> parent.children.delete_all # Ran without callbacks
Child Destroy (1.0ms) DELETE FROM "children" WHERE "children"."parent_id" = $1 [["parent_id", 1]]