0

在我的 Rails 应用程序中。我有我的基本模型 - 用户。有很多与用户相关的对象。

Class User 
 has_many :contents, dependent: destroy
 has_many :messages, dependent: destroy
 has_many :ratings, dependent: destroy
 has_many :groups, dependent: destroy
 ...
end

当我想从我的系统中删除用户(销毁用户对象)时,大约需要一分钟才能销毁其所有关联对象。处理此类案件的最佳方法是什么?

我想到的一种方法是:

在delayed_job 中销毁:

但是直到点用户对象在延迟作业中被销毁,这个用户不应该对其他人可见。通过在用户模型中删除标志而不获取结果来处理这种情况。但是我也使用 sphinx,并且需要确保这个用户也不会出现在 sphinx 结果中。

有没有更好的方法来处理这种情况?

4

2 回答 2

2

挑战在于,正如您可能已经知道的那样,该.destroy方法将加载每个子对象,然后调用它们的.destroy方法。

这里的价值是在进行最终销毁之前评估子级的任何回调。因此,如果孩子需要清理其他地方的任何东西,那么它会这样做。此外,如果依赖对象在销毁方法期间抛出错误,整个销毁操作将回滚,并且您最终不会有一些半死的对象一瘸一拐地四处走动。

.delete将销毁对象而不将它们加载到内存中或执行它们的回调。但是(显然)它不会执行他们的回调。

如果您想加快速度,您可以dependent: :delete按照 Octopus-Paul 的建议进行操作。这很好,但它不会破坏这些对象的依赖项,因此,例如,如果组有与它们相关联的消息,或者评级可能有与它们相关联的评论,那么这些都不会被破坏。

为了确保所有下游依赖项都被销毁并尊重任何必要的回调,我认为您能做的最好的事情就是编写一个自定义before_destroy方法,该方法进行所有清理但使用.deleteand.delete_all以加快速度。

这将产生遗留问题,因为下游编写代码的人不一定会预料到您的方法,但是您可以判断其风险。另一种方法(如您所说)是使用标志并异步完成工作。我想这在未来有更少的风险,但今天实施起来可能会更昂贵。

于 2013-09-29T17:48:21.977 回答
0

:依赖

控制关联对象在其所有者被销毁时发生的情况:

:destroy causes the associated object to also be destroyed
:delete causes the associated object to be deleted directly from the database (so callbacks will not execute)

删除会快得多,因为它会简单地为已删除用户的每个关联运行数据库查询。

在这里找到更多选项:http: //guides.rubyonrails.org/association_basics.html#options-for-has-one-dependent

于 2013-09-29T17:32:44.253 回答