1

他のテーブルとの 5 つの異なる has-many 関係を持つテーブルがあります。レコードを削除する前に、そのすべての子を別のレコードに移動する必要があります。これを達成するために、次のコードを使用します。

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" からすべての子を削除し、関連付けられたフィールド null を除くすべてのフィールドで単一の子を "target" に追加します。これは、「<<」がレコードを期待しており、レコードの配列を渡しているためだと思います。「<<」も引数のリストを受け入れることがわかったので、(splat演算子に注意してください)のようなものが必要だと思いますが、これtarget.send(assoc.name) << *self.send(assoc. name)を行うための有効な構文がわかりません。だから私の質問は2つです:

  1. 「<<」への入力用に任意の配列をどのように「スプラット」しますか?
  2. 子の再割り当てを正しく機能させるために必要なことは何ですか?
4

1 に答える 1

2

わかりました、ここに答えがあります:

1)target.send(assoc.name).send(:<<、*(self.send(assoc.name)))

2)元の手法は非効率的で、「n」個のSQL更新を生成し、それぞれが1つの子レコードを更新します。より効率的な手法はself.send(assoc.name).update_all(parent_id: target.id)です。リンクがどのように達成されるか(私の場合、ほとんどの場合、単一の外部キーフィールド)についての有罪の知識が必要です。これは、関連付けから反映される可能性があります)。

于 2012-06-05T23:32:38.823 に答える