ActiveRecord: How can I clone nested associations?

Shpigford picture Shpigford · Jul 15, 2011 · Viewed 17.3k times · Source

I'm currently cloning a single-level association like this:

class Survey < ActiveRecord::Base
  def duplicate
    new_template = self.clone
    new_template.questions << self.questions.collect { |question| question.clone } 
    new_template.save   
  end
end

So that clones the Survey then clones the Questions associated with that survey. Fine. That works quite well.

But what I'm having trouble with is that each question has_many Answers. So Survey has_many Questions which has_many Answers.

I can't figure out how to clone the answers properly. I've tried this:

def duplicate
  new_template = self.clone

  self.questions.each do |question|
    new_question = question.clone
    new_question.save

    question.answers.each do |answer|
      new_answer = answer.clone
      new_answer.save
      new_question.answers << answer
    end

    new_template.questions << question
  end

  new_template.save   
end

But that does some weird stuff with actually replacing the original answers then creating new ones, so ID's stop matching correctly.

Answer

fl00r picture fl00r · Jul 15, 2011

Use deep_clonable gem

new_survey = original_survey.clone :include => [:questions => :answers]