2011-01-27 10 views
0

は時々この作品、そして時にはそれがない:私は実験してる場合でActiveRecordの関連付けで<<を使用するのは適切でないことがありますか?

foo.bars << bar1 
foo.bars << bar2 

を更新:

class Foo 
    has_many :bars 
end 

class Bar 
    belongs_to :foo 
end 

foo = Foo.create 
bar1 = Bar.create 
bar2 = Bar.create 

foo.bars << [bar1, bar2] 

修正がそれらを個別に割り当てることですとfoobarは新しいオブジェクトではありません。

パターンが表示されない、または表示されない。しかも、ここでの質量割り当て(attr_accessible)の扱いが奇妙なようです。大量割り当てを試みた場合(開発中にバグを発見するのに役立つ)、例外を発生させるためのコードを用意していれば、動作しません。しかし、これらの例外を発生させない場合は、foo_idがどちらの場合でもattr_accessibleリストにないのに、動作します。通常

+0

"新しい"オブジェクトを言うとき、あなたはまだデータベースに保存されていない 'Bar'のインスタンスを意味しますか? –

+0

ええ、bar.new_record? == true' –

答えて

0

構文foo.bars << [bar1,bar2]には何の問題もありません。has_manyの関連付けに定義されているよう<<方法については、RailsのAPIは言う:

コレクション< <(オブジェクト、...)

は、彼らの外国 を設定することにより、 コレクションに1つまたは複数のオブジェクトを追加します。コレクションの主キーへのキー。 この操作はすぐに 親のオブジェクトの保存または更新の呼び出しを待たずにupdate sqlを起動します。

これは、(明らかに)一貫性のない動作についての手がかりを与える場合があります。

+0

RTFDには何人のSOユーザがかかります... –

2

あなたは「< < [X、Y]」あなたは配列に、xとyをプッシュしていないのではなく、xとyを含む新しい配列(それ多次元配列すること)を行う場合:

> test = Array.new 
=> [] 
> test << [1, 2] 
=> [[1, 2]] 
をあなたが代わりに "< <のx < < y" を使用する場合があります

:新しく作成されたオブジェクトの

> test = Array.new 
=> [] 
> test << 1 << 2 
=> [1, 2] 
+0

これはまさに正しいことですが、どうしてあなたが投票権を持っているのか分かりません。とにかく、あなたは正しいと思いますが、私は他のところで '<<'を使っていますので、 '<<'はどうしてアソシエーションを全く動かさないのでしょうか?ある場合?おそらく 'Foo'オブジェクトには' bar'がありません。 –

+0

Michaelが指摘したように、コレクションに1つのオブジェクトだけを追加している限り、親オブジェクトにコレクション内の要素がない場合でも '<< has_many'関連で' << 'が機能しない理由はありません。 –

+0

ジョン、正直言って私はそれがなぜいくつかのケースでうまくいったのか説明できません。 Imhoはhas_many関連にオブジェクトを追加するのに最も便利です。 –

1

を、私はhas_many関連のヘルパーメソッドを使用してお勧めしますまたはcreate

foo = Foo.create 
bar1 = foo.bars.create # saves the record 
bar2 = foo.bars.build # does not save the record 
bar2.save!    # actually creates the object 

これらのヘルパーは、普通のcreatenewのように、属性のハッシュを取ることができます - 唯一の違いは、彼らが自動的にあなたのための関連付けを設定されています。

あなたはfooに追加しようとしているバーオブジェクトがすでに存在する場合は、私の好みはバーオブジェクトに関連付けを設定するには、次のようになります。

foo = Foo.create # alternately Foo.find(1) 
bar = Bar.find(1) # alternately Bar.new, but then use Foo.bars.build 
bar.foo = foo 
bar.save! 

この方法は、それが問題を追跡するためにはるかに簡単です、例えば検証エラーを簡単に処理できます。 <<との唯一の違いは、再ロードせずにfoo.barsを最新の状態に保つことです。したがって、foo.barsが完全なバー(古いバーと新しく関連付けられたバー)の最新情報を必要とする場合は、<<を使用するとよいでしょう。

最後の脚注として、あなたも一度に全部を作成するbuildヘルパーを使用することができます。

foo = Foo.new 
bar1 = Foo.bars.build 
bar2 = Foo.bars.build 
foo.save!   # saves foo, bar1, and bar2 in one transaction, 
        # provided they are all valid 
+0

これはこれらの概念の概要ですが、私の質問に実際には触れません:-) –

+1

@John:マイケルは、配列を引数として '<<'を使って問題をカバーしましたが、 '<< 'を使って(そして何年もRailsをやっている)、' << 'を使うのではなく、私がしていることをカバーしたいと思っていました。あなたの質問はかなり曖昧だったので、ここではさまざまな問題を取り上げました。 – wuputah

+0

あなたは正しいです...私の質問は実際にはうまくいかないケースを実証しませんでした。ケースが発生した場合は、この質問を更新します。 –

関連する問題