ActiveRecord:如何克隆嵌套关联?
我目前正在克隆一个单级关联,如下所示:
class Survey < ActiveRecord::Base
def duplicate
new_template = self.clone
new_template.questions << self.questions.collect { |question| question.clone }
new_template.save
end
end
这样会克隆调查
,然后克隆与该调查关联的问题
。美好的。这效果很好。
但我遇到的问题是每个问题都有多个答案。因此调查 has_many 问题并得到 has_many 答案
。
我不知道如何正确克隆答案。我已经尝试过这个:
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
但这会做一些奇怪的事情,实际上替换了原始答案然后创建新答案,因此 ID 停止正确匹配。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用 deep_clonable gem
Use deep_clonable gem
您可能还喜欢 ActiveRecord 3.2 的 Amoeba gem。
对于您的情况,您可能希望使用配置 DSL 中提供的
nullify
、regex
或prefix
选项。它支持
has_one
、has_many
和has_and_belongs_to_many
关联的简单自动递归复制、字段预处理以及可应用的高度灵活且强大的配置DSL无论是对于模型还是在飞行中。请务必查看 Amoeba 文档,但使用非常简单......
只需
或添加
到您的 然后, Gemfile
将阿米巴块添加到模型中,并照常运行 dup 方法。
您还可以通过多种方式控制复制哪些字段,但例如,如果您想防止注释重复,但您想要维护相同的标签,你可以执行以下操作:
您还可以预处理字段以帮助指示前缀和后缀以及正则表达式的唯一性。此外,还有许多选项,因此您可以根据自己的目的以最易读的方式进行编写:
关联的递归复制很容易,只需在子模型上启用amoeba
配置 DSL 还有更多选项,因此请务必查看文档。
享受! :)
You may also like the Amoeba gem for ActiveRecord 3.2.
In your case, you probably want to make use of the
nullify
,regex
orprefix
options available in the configuration DSL.It supports easy and automatic recursive duplication of
has_one
,has_many
andhas_and_belongs_to_many
associations, field preprocessing and a highly flexible and powerful configuration DSL that can be applied both to the model and on the fly.be sure to check out the Amoeba Documentation but usage is pretty easy...
just
or add
to your Gemfile
then add the amoeba block to your model and run the
dup
method as usualYou can also control which fields get copied in numerous ways, but for example, if you wanted to prevent comments from being duplicated but you wanted to maintain the same tags, you could do something like this:
You can also preprocess fields to help indicate uniqueness with both prefixes and suffixes as well as regexes. In addition, there are also numerous options so you can write in the most readable style for your purpose:
Recursive copying of associations is easy, just enable amoeba on child models as well
The configuration DSL has yet more options, so be sure to check out the documentation.
Enjoy! :)
在不使用 gem 的情况下,您可以执行以下操作:
然后您可以调用:
这会将上一个调查中的所有问题复制到新调查中并将它们绑定在一起。
Without using gems, you can do the following:
Then you can call:
That will duplicate all questions from last Survey to new Survey and tie them.
难道不是吗..
Shouldn't it be..
您还可以为rails dup方法添加别名,如下所示:
然后您可以这样做
You can also alias the rails dup method, as follows:
and then you can do this