关联的 ActiveRecord .dup

Dan*_*ell 3 activerecord ruby-on-rails ruby-on-rails-4

我有两个模型,SurveyQuestion. 一个Survey has_many :questions和一个Question belongs_to :survey。我知道我可以Survey通过执行以下操作来复制一个实例:

old_survey = Survey.last
new_survey = old_survey.dup
Run Code Online (Sandbox Code Playgroud)

现在new_survey将是相同的old_survey,只是它的id属性nil。我想知道的是我如何也可以复制关联的对象,最好不要遍历它们或安装 3rd 方 gem。

我想做这样的事情:

old_survey = Survey.last
new_survey = old_survey.dup
new_survey.questions = old_survey.questions.dup
old_survey.save!
Run Code Online (Sandbox Code Playgroud)

上面的代码不起作用。如果我打电话,new_survey.questions.pluck(:id)我可以看到 ids 匹配old_survey.questions.pluck(:id),这是不可取的。

显然,我可以遍历old_survey.questions,但我想找到一种更有效的方法来实现这一点。

NM *_*ker 5

您可以使用deep_clonablegem:https : //github.com/moiristo/deep_cloneable

然后你可以做这样的事情:

old_survey.dup include: :questions
Run Code Online (Sandbox Code Playgroud)

但这会为您的应用程序添加另一个依赖项。最简单的方法是遍历旧的调查问题并根据需要分配 id。你的问题表明你想避免这样做,但我真的认为这是最好的(也是最轻量级的)选择。

如果您愿意遍历关联的对象,这应该可以解决问题:

def clone_with_questions
  new_survey = self.dup
  new_survey.save
  new_survey.questions = self.questions
  new_survey
end

@new_survey = Survey.last.clone_with_questions
Run Code Online (Sandbox Code Playgroud)

可能需要稍微调整一下才能与您的应用程序一起使用,但这是总体思路。

  • 仅供参考 - 这将打破您原来的关联,因为“new_survey.questions = self.questions”会将问题从旧调查移至新调查。 (2认同)