在我的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结果。
有没有更好的方法来处理此类案件?
答案 0 :(得分:2)
挑战在于,正如您可能已经知道的那样,.destroy
方法将加载每个子对象,然后调用它们的.destroy
方法。
这个值是在进行最终销毁之前评估子节点上的任何回调。因此,如果孩子需要在其他地方清理任何东西,那么它就会这样做。此外,如果依赖对象在destroy方法期间抛出错误,整个销毁操作将回滚,并且您不会最终得到一些半死的对象。
.delete
将销毁对象而不将其加载到内存中或执行其回调。然而(显然)它不会执行他们的回调。
如果你想加快速度,你可以像Octopus-Paul所说的那样简单地做dependent: :delete
。这样就可以了,但是它不会破坏这些对象上的依赖项,因此,例如,如果组中有与之关联的消息,或者评级中有与之关联的注释,那么这些对象都不会被销毁。
为了确保所有下游家属都被销毁并且任何必要的回调都得到尊重,我认为您可以做的最好的事情是编写一个自定义before_destroy
方法,该方法可以清除所有内容,但使用.delete
和{{ 1}}以加快速度。
这将产生遗留问题,因为有人编写下游代码并不一定会预测您的方法,但您可以判断其风险。另一种选择(正如你所说)是使用一个标志并异步完成工作。我想这将来风险较小,但今天实施的成本可能更高。
答案 1 :(得分: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