首先,当关联的内容很多时,我们继续使用 SQL DELETE 而不是 Rails destroy 使用手动删除过程。 (虽然这可能对你不起作用,如果你不小心引入了很多回调依赖,在记录被销毁后会做一些事情)
def custom_delete
self.class.transaction do
related_objects.delete_all
related_objects_2.delete_all
delete
end
end
如果你发现自己一直在写这个,你可以简单地将它包装在接受要删除的相关对象键列表的类方法中。
class ActiveRecord::Base
class << self
def bulk_delete_related(*args)
define_method "custom_delete" do
ActiveRecord::Base.transaction do
args.each do |field|
send(field).delete_all
end
end
delete
end
end
end
end
class SomeModel < ActiverRecord::Base
bulk_delete :related_objects, :related_objects2, :related_object
end
我直接在 ActiveRecord::Base 类中插入了类方法,但可能你最好将它提取到模块中。此外,这只会加快速度,但不能解决最初的问题。
其次,您可以引入 FK 约束(我们这样做是为了确保完整性,因为我们做了很多自定义 SQL)。只要有链接的对象,它将以不会删除用户的方式工作。虽然它可能不是你想要的。为了提高此解决方案的有效性您始终可以将用户删除委托给后台作业,该作业将重试删除用户,直到它实际上可以被删除(没有新对象放入)
或者,在某些情况下,您可以像我之前的工作那样做相反的事情。如果删除用户比确保没有僵尸记录更重要,请不时使用一些滑动过程来清理。
最后,事实在中间的某个地方 - 将约束应用于在删除用户之前肯定需要清理的关系,并仅依靠清扫器删除不应该干扰用户删除的不太重要的关系。
问题不是小事,但应该可以在一定程度上解决。