@model.destroy 和 @model.delete 有什么区别?
例如:
Model.find_by(col: "foo").destroy_all
//and
Model.find_by(col: "foo").delete_all
我使用其中一个或另一个真的很重要吗?
@model.destroy 和 @model.delete 有什么区别?
例如:
Model.find_by(col: "foo").destroy_all
//and
Model.find_by(col: "foo").delete_all
我使用其中一个或另一个真的很重要吗?
基本上,destroy
会运行模型上的任何回调函数,而 delete
则不会。
摘自 Rails API:
ActiveRecord::Persistence.delete
在数据库中删除记录并冻结此实例以反映不应进行更改(因为它们无法持久化)。返回被冻结的实例。
仅使用记录的主键上的SQL DELETE语句简单地删除行,并且不执行任何回调。
要强制执行对象的before_destroy和after_destroy回调或任何:dependent关联选项,请使用#destroy。
ActiveRecord::Persistence.destroy
在数据库中删除记录并冻结此实例以反映不应进行更改(因为它们无法持久化)。
与destroy相关联的一系列回调。如果before_destroy回调返回false,则取消操作,并且destroy返回false。有关详细信息,请参见ActiveRecord :: Callbacks。
delete
只会从数据库中删除当前对象记录,而不会删除与之关联的子记录。
destroy
会从数据库中删除当前对象记录以及其关联的子记录。
它们的使用非常重要:
如果你的多个父对象共享相同的子对象,那么在特定的父对象上调用 destroy
将删除在其他多个父对象之间共享的子对象。
ActiveRecord
对象上调用destroy
或destroy_all
方法时,ActiveRecord
的“销毁”过程就会开始。该过程会分析您正在删除的类,并确定其相关依赖关系、运行验证等操作。delete
或delete_all
方法时,ActiveRecord
只是试图对数据库运行DELETE FROM tablename WHERE conditions
查询语句,并不执行其他ActiveRecord
级别的任务。示例:
Class User
has_many :contents, dependent: :destroy
end
user = User.last
user.delete -> only user
user.destroy -> delete user , and contents of user
delete
会从数据库中删除当前记录(无回调)
destroy
会删除当前记录及其关联记录(有回调)
delete_all
和destroy_all
同理。
两种方法之间有很大的区别。如果您希望快速删除记录而不调用模型回调,请使用delete_all。
如果您关心模型回调,则使用destroy_all。
来自官方文档。
http://apidock.com/rails/ActiveRecord/Base/destroy_all/class
destroy_all(conditions = nil) 公开方法
通过实例化每个记录并调用其destroy方法来销毁与条件匹配的记录。将执行每个对象的回调(包括:dependent关联选项和before_destroy/after_destroy观察者方法)。返回已销毁的对象集合;每个对象将被冻结,以反映不应进行任何更改(因为它们无法被持久化)。
注意:当同时删除多条记录时,实例化、回调执行和每条记录的删除可能非常耗时。它会为每个记录生成至少一个SQL DELETE查询语句(或更多,以强制执行回调)。如果您想快速删除多行,而不必考虑它们的关联或回调,请改用delete_all。
文档:
对于has_many,destroy和destroy_all将始终调用要删除的记录的destroy方法,以便运行回调。但是,delete和delete_all将根据:dependent选项指定的策略执行删除操作,或者如果没有给出:dependent选项,则它将遵循默认策略。默认策略是什么都不做(将父ID设置为外键),除了has_many:through,其中默认策略是delete_all(删除联接记录,而不运行其回调)。
delete
命令在 ActiveRecord::Association.has_many
和 ActiveRecord::Base
中的作用不同。对于后者,delete
将执行 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]]
before_destroy
)。
model#before_destroy
回调函数,可以在特定条件下停止最终的destroy()
调用。 - Todd