两者有什么区别

@model.destroy和@model.delete

例如:

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

我用哪个真的重要吗?


当前回答

Delete只会从db中删除当前对象记录,而不会从db中删除其关联的子记录。

Destroy将从db中删除当前对象记录,并从db中删除其关联的子记录。

它们的使用真的很重要:

如果你的多个父对象共享公共的子对象,那么在特定的父对象上调用destroy将删除在其他多个父对象中共享的子对象。

其他回答

Delete只会从db中删除当前对象记录,而不会从db中删除其关联的子记录。

Destroy将从db中删除当前对象记录,并从db中删除其关联的子记录。

它们的使用真的很重要:

如果你的多个父对象共享公共的子对象,那么在特定的父对象上调用destroy将删除在其他多个父对象中共享的子对象。

例子:

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也是如此

基本上,“delete”直接向数据库发送查询以删除记录。在这种情况下,Rails不知道它正在删除的记录中有什么属性,也不知道是否有任何回调(比如before_destroy)。

“destroy”方法获取传递的id,使用“find”方法从数据库中获取模型,然后对其调用destroy。这意味着回调被触发。

如果你不想触发回调或者你想要更好的性能,你会想要使用“delete”。否则(大多数时候)你会想要使用“destroy”。

已经有很多答案了;我还想再来点。

文档:

For has_many, destroy and destroy_all will always call the destroy method of the record(s) being removed so that callbacks are run. However delete and delete_all will either do the deletion according to the strategy specified by the :dependent option, or if no :dependent option is given, then it will follow the default strategy. The default strategy is to do nothing (leave the foreign keys with the parent ids set), except for has_many :through, where the default strategy is delete_all (delete the join records, without running their callbacks).

对于ActiveRecord::Association, delete verbose的工作方式不同。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]]

当你在一个ActiveRecord对象上调用destroy或destroy_all时,ActiveRecord ' destroy '过程被启动,它会分析你要删除的类,它会确定它应该为依赖项做什么,运行验证等。

当你在一个对象上调用delete或delete_all时,ActiveRecord仅仅尝试对数据库运行delete FROM表名WHERE条件查询,不执行其他ActiveRecord级别的任务。