Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
590 views
in Technique[技术] by (71.8m points)

ruby on rails - Delete Orphaned Parent

I have a relationship like so:

Parent
  has_many :children

Child
  belongs_to :parent

What I want to do is to delete the parent if there are no more children left. So to do this I have:

Child
    before_destroy :destroy_orphaned_parent

    def destroy_orphaned_parent
      parent.children.each do |c|
        return if c != self
      end
      parent.destroy
    end

This works fine, however I also want to cascade the delete of the parent to the child. E.g. I would normally do:

Parent
  has_many :children, :dependent => :destroy

This causes the WebRick server to crash when I test it. I assume this is due to an infinite loop of the last child deleting the parent deleting the child etc.

I am starting to think that there is a better way to do this? Anyone have any ideas? Is there a way to prevent this recursion?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I accomplished this in the following way:

  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

As per Anwar's suggestion, this can also be accomplished using an around callback, as follows:

  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

I haven't tested the above solution, so feel free to update it, if necessary.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...