delete_all vs destroy_all?

我正在寻找从表中删除logging的最佳方法。 例如,我有一个用户的用户ID跨越很多表。 我想删除这个用户和每个在所有表中都有他的ID的logging。

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

这工作,并从所有表中删除用户的所有引用,但我听说, destroy_all是非常stream程重,所以我试过delete_all 。 它只将用户从他自己的用户表中删除,并且所有其他表中的id都为空,但保留完整的logging。 有人可以分享执行此类任务的正确stream程吗?

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

你是对的。 如果你想删除用户和所有关联的对象 – > destroy_all但是,如果你只是想删除用户而不禁止所有关联的对象 – > delete_all

根据这个post: Rails:dependent =>:destroy VS:dependent =>:delete_all

  • destroy / destroy_all :通过调用它们的销毁方法,关联的对象被销毁
  • delete / delete_all :所有关联的对象都会立即被销毁,而不会调用它们:destroy方法

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

如果你必须在大型数据集上执行一些像destroy_all()这样的操作,我可能不会从应用程序中执行它,并且手动处理它。 如果数据集足够小,则不会受到太多的伤害。

为了避免destroy_all实例化所有logging并一次性销毁它们,您可以直接从模型类中使用它。

所以,而不是:

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

你可以做 :

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

结果是一个查询来销毁所有关联的logging

我做了一个小gem ,可以减轻在某些情况下手动删除相关logging的需要。

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

依赖于::delete_recursively

在销毁logging时,使用此选项关联的所有logging都将被recursion删除(即跨模型),而不实例化任何logging。

请注意,就像dependent :: delete或dependent :: delete_all一样,这个新选项不会触发从属logging的around / before / after_destroycallback。

但是,依赖于::可以在一系列模型链中的任意位置销毁关联,这些关联与dependent :: delete_recursively关联。 破坏选项将正常工作在任何地方上下线,实例化和销毁所有相关logging,从而也触发他们的callback。