删除孤儿父母

时间:2011-05-03 07:22:28

标签: ruby-on-rails ruby activerecord

我有这样的关系:

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服务器在测试时崩溃。我假设这是由于最后一个孩子的无限循环删除父母删除孩子等。

我开始认为有更好的方法可以做到这一点?有人有主意吗?有没有办法防止这种递归?

5 个答案:

答案 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)

一些想法:

答案 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