删除孤儿父母
我有这样的关系:
Parent has_many :children Child belongs_to :parent
我想要做的是删除父母,如果没有更多的孩子。 所以要做到这一点,我有:
Child before_destroy :destroy_orphaned_parent def destroy_orphaned_parent parent.children.each do |c| return if c != self end parent.destroy end
这工作正常,但我也想将父级的删除级联到子级。 我通常会这样做:
Parent has_many :children, :dependent => :destroy
这会导致WebRick服务器在测试时崩溃。 我假设这是由于最后一个孩子的无限循环删除父母删除孩子等。
我开始认为有更好的方法来做到这一点? 有人有主意吗? 有没有办法防止这种递归?
一些想法:
-
您可以删除
after_destroy
孤立父after_destroy
(使用http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/a3f12d578f5a2619上的语句查找它们) -
您可以在包含父ID的
before_destroy
中设置一些实例变量,然后在after_destroy
回调中根据此id进行查找,并根据after_destroy
计数来决定是否删除父项
我通过以下方式完成了这项工作:
before_destroy :find_parent after_destroy :destroy_orphaned_parent def find_parent @parent = self.parent end def destroy_orphaned_parent if @parent.children.length == 0 @parent.destroy end end
根据Anwar的建议,这也可以使用around
回调来完成,如下所示:
around_destroy :destroy_orphaned_parent def destroy_orphaned_parent parent = self.parent yield # executes a DELETE database statement if parent.children.length == 0 parent.destroy end end
我没有测试过上述解决方案,如有必要,请随时更新。
使用after_destroy
回调。
after_destroy :release_parent def release_parent if parent.children.count.zero? parent.destroy end end
使用Rails 3.2.15
您可以使用around_destroy
回调来完成此操作
around_destroy :destroy_orphaned_parent def destroy_orphaned_parent @parent = self.parent yield @parent.destroy if @parent.children.length == 0 end
after_destroy :destroy_parent, if: parent_is_orphan? private def parent_is_orphan? parent.children.count.zero? end def destroy_parent parent.destroy end