Ruby-on-rails delete_all vs destroy_all?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6698207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
delete_all vs destroy_all?
提问by glogic
I am looking for the best approach to delete records from a table. For instance, I have a user whose user ID is across many tables. I want to delete this user and every record that has his ID in all tables.
我正在寻找从表中删除记录的最佳方法。例如,我有一个用户,其用户 ID 跨多个表。我想删除此用户以及所有表中具有其 ID 的每条记录。
u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all
u.sources.destroy_all
u.user_stats.destroy_all
u.delete
This works and removes all references of the user from all tables, but I heard that destroy_allwas very process heavy, so I tried delete_all. It only removes the user from his own user table and the idfrom all the other tables are made null, but leaves the records intact in them. Can someone share what the correct process is for performing a task like this?
这有效并从所有表中删除了用户的所有引用,但我听说这destroy_all是非常繁重的过程,所以我尝试了delete_all. 它只从他自己的用户表中删除用户,并且id所有其他表中的 都为空,但保留其中的记录完好无损。有人可以分享执行此类任务的正确流程是什么吗?
I see that destroy_allcalls the destroyfunction on all associated objects but I just want to confirm the correct approach.
我看到在所有关联对象上destroy_all调用该destroy函数,但我只想确认正确的方法。
回答by Sandro Munda
You are right. If you want to delete the User and all associated objects -> destroy_allHowever, if you just want to delete the User without suppressing all associated objects -> delete_all
你是对的。如果你想删除 User 和所有关联的对象 ->destroy_all但是,如果你只是想删除 User 而不抑制所有关联的对象 ->delete_all
According to this post : Rails :dependent => :destroy VS :dependent => :delete_all
根据这篇文章:Rails :dependent => :destroy VS :dependent => :delete_all
destroy/destroy_all: The associated objects are destroyed alongside this object by calling their destroy methoddelete/delete_all: All associated objects are destroyed immediately without calling their :destroy method
destroy/destroy_all: 关联的对象通过调用它们的 destroy 方法与这个对象一起销毁delete/delete_all: 立即销毁所有关联的对象,而不调用它们的 :destroy 方法
回答by Ryan Her
delete_all is a single SQL DELETE statement and nothing more. destroy_all calls destroy() on all matching results of :conditions (if you have one) which could be at least NUM_OF_RESULTS SQL statements.
delete_all 是单个 SQL DELETE 语句,仅此而已。destroy_all 对 :conditions 的所有匹配结果(如果有)调用 destroy() ,这些结果可能至少是 NUM_OF_RESULTS SQL 语句。
If you have to do something drastic such as destroy_all() on large dataset, I would probably not do it from the app and handle it manually with care. If the dataset is small enough, you wouldn't hurt as much.
如果您必须在大型数据集上执行诸如 destroy_all() 之类的激烈操作,我可能不会从应用程序中执行此操作并小心地手动处理它。如果数据集足够小,您就不会受到太大的伤害。
回答by simon-olivier
To avoid the fact that destroy_allinstantiates all the records and destroys them one at a time, you can use it directly from the model class.
为了避免destroy_all实例化所有记录并一次销毁它们的事实,您可以直接从模型类中使用它。
So instead of :
所以而不是:
u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all
You can do :
你可以做 :
u = User.find_by_name('JohnBoy')
UsageIndex.destroy_all "user_id = #{u.id}"
The result is one query to destroy all the associated records
结果是一个销毁所有关联记录的查询
回答by Janosch
I've made a small gemthat can alleviate the need to manually delete associated records in some circumstances.
我制作了一个小宝石,可以减轻在某些情况下手动删除关联记录的需要。
This gem adds a new option for ActiveRecord associations:
dependent: :delete_recursively
When you destroy a record, all records that are associated using this option will be deleted recursively (i.e. across models), without instantiating any of them.
Note that, just like dependent: :delete or dependent: :delete_all, this new option does not trigger the around/before/after_destroy callbacks of the dependent records.
However, it is possible to have dependent: :destroy associations anywhere within a chain of models that are otherwise associated with dependent: :delete_recursively. The :destroy option will work normally anywhere up or down the line, instantiating and destroying all relevant records and thus also triggering their callbacks.
这个 gem 为 ActiveRecord 关联添加了一个新选项:
依赖: :delete_recursively
当您销毁一条记录时,所有使用此选项关联的记录将被递归删除(即跨模型),而不会实例化任何记录。
请注意,就像dependent: :delete 或dependent: :delete_all 一样,这个新选项不会触发相关记录的around/before/after_destroy 回调。
然而,在一个模型链中的任何地方都可能有dependent::destroy 关联,否则这些关联与dependent::delete_recursively 相关联。:destroy 选项将正常工作在线上或下的任何地方,实例化和销毁所有相关记录,从而触发它们的回调。

