两者有什么区别
@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
我用哪个真的重要吗?
当前回答
例子:
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也是如此
其他回答
例子:
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只会从db中删除当前对象记录,而不会从db中删除其关联的子记录。
Destroy将从db中删除当前对象记录,并从db中删除其关联的子记录。
它们的使用真的很重要:
如果你的多个父对象共享公共的子对象,那么在特定的父对象上调用destroy将删除在其他多个父对象中共享的子对象。
基本上,“delete”直接向数据库发送查询以删除记录。在这种情况下,Rails不知道它正在删除的记录中有什么属性,也不知道是否有任何回调(比如before_destroy)。
“destroy”方法获取传递的id,使用“find”方法从数据库中获取模型,然后对其调用destroy。这意味着回调被触发。
如果你不想触发回调或者你想要更好的性能,你会想要使用“delete”。否则(大多数时候)你会想要使用“destroy”。
基本上destroy会运行模型上的任何回调,而delete则不会。
来自Rails API:
ActiveRecord::Persistence.delete Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can't be persisted). Returns the frozen instance. The row is simply removed with an SQL DELETE statement on the record's primary key, and no callbacks are executed. To enforce the object's before_destroy and after_destroy callbacks or any :dependent association options, use #destroy. ActiveRecord::Persistence.destroy Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can't be persisted). There's a series of callbacks associated with destroy. If the before_destroy callback return false the action is cancelled and destroy returns false. See ActiveRecord::Callbacks for further details.
已经有很多答案了;我还想再来点。
文档:
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]]