Delete_all vs destroy_all

我正在寻找从表中删除记录的最佳方法。例如,我有一个用户,其用户ID横跨多个表。我想删除这个用户和所有表中具有他的ID的每个记录。

u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all
u.sources.destroy_all
u.user_stats.destroy_all
u.delete

这可以工作,并从所有表中删除用户的所有引用,但我听说destroy_all是非常繁重的进程,所以我尝试了delete_all。它只是从他自己的用户表中删除用户,而从所有其他表中删除id则为空,但保留其中的记录完整。有人能分享一下执行这样的任务的正确流程吗?

我看到destroy_all在所有关联对象上调用destroy函数,但我只想确认正确的方法。

133223 次浏览

你是对的。如果您想删除User和所有关联对象-> destroy_all . exe 然而,如果你只是想删除User而不抑制所有关联对象-> delete_all

. bb0 . bb0

. bb0

根据这篇文章:Rails:dependent =>:destroy VS:dependent =>: delete_all

  • destroy / destroy_all:通过调用该对象的destroy方法,将关联对象与该对象一起销毁
  • delete / delete_all:立即销毁所有关联对象,而不调用它们的:destroy方法

delete_all是一个单独的SQL DELETE语句,仅此而已。destroy_all对:conditions(如果有的话)的所有匹配结果调用destroy(),至少可以是NUM_OF_RESULTS SQL语句。

如果你必须在大型数据集上做一些激烈的事情,比如destroy_all(),我可能不会从应用程序中这样做,而是小心地手动处理它。如果数据集足够小,你就不会受到太大的伤害。

为了避免destroy_all实例化所有记录并一次销毁它们一个的事实,你可以直接从模型类中使用它。

所以不要:

u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all

你可以:

u = User.find_by_name('JohnBoy')
UsageIndex.destroy_all "user_id = #{u.id}"

结果是一个查询销毁所有相关记录

我已经做了一个小的宝石,它可以减轻在某些情况下手动删除相关记录的需要。

这个宝石为ActiveRecord关联添加了一个新选项:

依赖:delete_recursively

当你销毁一个记录时,所有使用这个选项关联的记录将被递归地删除(即跨模型),而不实例化它们中的任何一个。

注意,就像dependent::delete或dependent::delete_all一样,这个新选项不会触发依赖记录的around/before/after_destroy回调。

然而,在模型链的任何地方都可以使用dependent::destroy关联,否则就会与dependent:: delete_recurrecursive关联。destroy选项将在上下一行的任何位置正常工作,实例化并销毁所有相关记录,从而触发它们的回调。