ActiveRecord将所有孩子移动到另一个记录

时间:2012-06-05 18:06:03

标签: ruby-on-rails activerecord associations splat

我有一个表与其他表有五种不同的有多种关系。在删除记录之前,我需要将其所有孩子移到另一个记录中。为此,我使用以下代码:

self.class.reflect_on_all_associations.select {|assoc| assoc.macro == :has_many }.each do |assoc|
  target.send(assoc.name) << self.send(assoc.name)
end

基本上,这归结为target.child-association << self.child-association。但这不能正常工作,从“self”中删除所有子项,并将一个子项添加到“target”,除了关联的字段null之外的所有字段。我认为这是因为“&lt;&lt;”期待一个记录,我正在传递一系列记录。我看到“&lt;&lt;”也接受一个参数列表,所以我认为我需要target.send(assoc.name) << *self.send(assoc. name)之类的东西(请注意splat运算符),但我无法找到这样做的有效语法。所以我的问题是两个:

  1. 如何“splat”任意数组以输入“&lt;&lt;”?
  2. 是否需要使儿童重新分配正常工作?

1 个答案:

答案 0 :(得分:2)

好的,这是答案:

1)target.send(assoc.name).send(:&lt;&lt;,*(self.send(assoc.name)))

2)原始技术效率低下,产生了&#39; n&#39; SQL更新,每个更新一个子记录。效率更高的技术是self.send(assoc.name).update_all(parent_id: target.id)。它需要知道链接是如何完成的(在我的情况下,大多数情况下,单个外键字段)我认为可以从关联中反映出来。