两者有什么区别
@model.destroy和@model.delete
@model.destroy
@model.delete
例如:
Model.find_by(col: "foo").destroy_all //and Model.find_by(col: "foo").delete_all
我用哪个真的重要吗?
基本上,“delete”直接向数据库发送查询以删除记录。在这种情况下,Rails不知道它正在删除的记录中有什么属性,也不知道是否有任何回调(比如before_destroy)。
before_destroy
“destroy”方法获取传递的id,使用“find”方法从数据库中获取模型,然后对其调用destroy。这意味着回调被触发。
如果你不想触发回调或者你想要更好的性能,你会想要使用“delete”。否则(大多数时候)你会想要使用“destroy”。
如果你关心你的模型回调,那么使用destroy_all
来自官方文件
http://apidock.com/rails/ActiveRecord/Base/destroy_all/class
Destroy_all(条件= nil)公共 通过实例化每条记录来销毁匹配条件的记录 并调用它的destroy方法。执行每个对象的回调 (包括:依赖关联选项和 before_destroy/after_destroy观察者方法)。返回集合 被摧毁的物品;每一个都将被冻结,以反映 不应该做任何更改(因为它们不能被持久化) 注:实例化,回调执行,删除每条记录 当您一次删除许多记录时,可能会花费时间。它 每条记录至少生成一个SQL DELETE查询(或可能更多), 执行你的回调)。如果你想快速删除很多行, 不用考虑它们的关联或回调,使用delete_all即可 相反。< / p >
Destroy_all(条件= nil)公共
通过实例化每条记录来销毁匹配条件的记录 并调用它的destroy方法。执行每个对象的回调 (包括:依赖关联选项和 before_destroy/after_destroy观察者方法)。返回集合 被摧毁的物品;每一个都将被冻结,以反映 不应该做任何更改(因为它们不能被持久化)
注:实例化,回调执行,删除每条记录 当您一次删除许多记录时,可能会花费时间。它 每条记录至少生成一个SQL DELETE查询(或可能更多), 执行你的回调)。如果你想快速删除很多行, 不用考虑它们的关联或回调,使用delete_all即可 相反。< / p >
当你在一个ActiveRecord对象上调用destroy或destroy_all时,ActiveRecord“销毁”过程被启动,它会分析你要删除的类,它会确定它应该为依赖项做什么,运行验证等。
ActiveRecord
destroy
destroy_all
当你在一个对象上调用delete或delete_all时,ActiveRecord只是尝试对db运行DELETE FROM tablename WHERE conditions查询,不执行其他ActiveRecord级任务。
delete
delete_all
DELETE FROM tablename WHERE conditions
基本上,destroy会运行模型上的任何回调,而delete不会。
从Rails API:
ActiveRecord::Persistence.delete
删除数据库中的记录并冻结该实例,以反映不应进行任何更改(因为它们不能持久保存)。返回冻结的实例。 只需在记录的主键上使用SQL DELETE语句删除该行,并且不执行任何回调。 要强制执行对象的before_destroy和after_destroy回调或任何:依赖关联选项,请使用#destroy。 李< /引用> < / > < p > ActiveRecord::Persistence.destroy 删除数据库中的记录并冻结该实例,以反映不应进行任何更改(因为它们不能持久保存)。 有一系列与destroy相关的回调。如果before_destroy回调函数返回false,则动作被取消,destroy返回false。更多细节请参见ActiveRecord::Callbacks。 李< /引用> < / >
删除数据库中的记录并冻结该实例,以反映不应进行任何更改(因为它们不能持久保存)。返回冻结的实例。
只需在记录的主键上使用SQL DELETE语句删除该行,并且不执行任何回调。
要强制执行对象的before_destroy和after_destroy回调或任何:依赖关联选项,请使用#destroy。
ActiveRecord::Persistence.destroy
删除数据库中的记录并冻结该实例,以反映不应进行任何更改(因为它们不能持久保存)。 有一系列与destroy相关的回调。如果before_destroy回调函数返回false,则动作被取消,destroy返回false。更多细节请参见ActiveRecord::Callbacks。 李< /引用> < / >
删除数据库中的记录并冻结该实例,以反映不应进行任何更改(因为它们不能持久保存)。
有一系列与destroy相关的回调。如果before_destroy回调函数返回false,则动作被取消,destroy返回false。更多细节请参见ActiveRecord::Callbacks。
delete只会从db中删除当前对象记录,而不会从db中删除其相关的子记录。
destroy将从db中删除当前对象记录,并从db中删除其关联的子记录。
它们的使用真的很重要:
如果你的多个父对象共享公共的子对象,那么在特定的父对象上调用destroy将删除在其他多个父对象中共享的子对象。
已经有很多答案了;我还想再来点。
文档:
对于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运行
ActiveRecord::Association.has_many
ActiveRecord::Base
SQL DELETE
:dependent
dependent: :destroy例子:
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]]
例子:
Class User has_many :contents, dependent: :destroy end user = User.last user.delete -> only user user.destroy -> delete user , and contents of user
delete将从db中删除当前记录(没有回调)
destroy将删除当前记录和相关记录(有回调)
delete_all和destroy_all也是如此