我正在寻找从表中删除记录的最佳方法。例如,我有一个用户,其用户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函数,但我只想确认正确的方法。


你说得对。如果要删除User及其所有关联对象-> destroy_all . sh 但是,如果您只是想删除User而不删除所有关联对象-> delete_all . zip

根据这个帖子: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}"

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


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

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.