我有这样的关系:
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服务器在测试时崩溃。我假设这是由于最后一个孩子的无限循环删除父母删除孩子等。
我开始认为有更好的方法可以做到这一点?有人有主意吗?有没有办法防止这种递归?
答案 0 :(得分:8)
我通过以下方式完成了这项工作:
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
我没有测试过上述解决方案,如有必要,请随时更新。
答案 1 :(得分:7)
一些想法:
您可以删除孤立的父母
after_destroy
{找到他们使用
像一个声明的声明
http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/a3f12d578f5a2619)
您可以在before_destroy
中设置一个包含父ID的实例变量,然后在after_destroy
回调中根据此ID进行查找,并根据计数决定是否删除其父项孩子们
答案 2 :(得分:3)
使用after_destroy
回调。
after_destroy :release_parent
def release_parent
if parent.children.count.zero?
parent.destroy
end
end
使用Rails 3.2.15
答案 3 :(得分:3)
您可以使用around_destroy
回调
around_destroy :destroy_orphaned_parent
def destroy_orphaned_parent
@parent = self.parent
yield
@parent.destroy if @parent.children.length == 0
end
答案 4 :(得分:0)
after_destroy :destroy_parent, if: parent_is_orphan?
private
def parent_is_orphan?
parent.children.count.zero?
end
def destroy_parent
parent.destroy
end