我已就此问题检查过一堆问题,包括here,here和here。我似乎无法弄清楚这里出了什么问题。
这是我的复制方法:
def copy(new_period)
copy = self.dup
copy.report_id = Report.maximum(:report_id).next
copy.period_id = new_period
copy.responses = self.responses.dup
copy.save
end
此方法正确制作报表模型的副本,并按预期将其分配给新期间。它还将所有孩子从原始报告移动到新报告而不重复,这是不期望的。我不明白为什么会这样。
有人有什么想法吗?
答案 0 :(得分:3)
我认为有罪的是以下一行
copy.responses = self.responses.dup
self.responses
的返回值为ActiveRecord::Relation
。当您调用dup时,您将复制关系实例,而不是范围指向的资源。
如果要复制响应对象,则需要先加载它们。
copy.responses = self.responses.map { |response| response.dup }
或
copy.responses = self.responses.map(&:dup)
答案 1 :(得分:0)
dup执行浅拷贝。它也不会复制其所有子对象。这对于数组和散列也很重要。
解决方案是基本上为您的模型编写克隆方法:
def clone(new_period)
copy = self.class.new self.attributes.slice(*%w{attributes to copy})
copy.report_id = Report.maximum(:report_id).next
copy.period_id = new_period
copy.responses = Response.clone_multiple(self.responses)
copy.save
end
与响应类似,添加一个类方法来克隆集合:
class << self
def clone_multiple(collection)
collection.map do |response|
copy = self.new(response.attributes.slice(*%w{attributes to clone})
copy.save
copy
end
end
end