2011-12-08 4 views
0

has_manyアドレスのPersonモデルがあるとします。コントローラの中で私が行うのは3.times{@person.addresses.build}なので、次のコードはaddressのtext_fieldsを3セット生成するべきですか?何らかの理由で、私はコントローラに何個のアドレスを構築しても、1つのアドレス形式しか得られません。私は3.0リソースごとにfields_forフォームを作成しますか?

<%= form_for @person do |person_form| %> 
    <%= person_form.fields_for :addresses do |address_fields| %> 
     Street : <%= address_fields.text_field :street %> 
    <% end %> 
    <% end %> 
+1

Personモデルに 'accepts_nested_attributes_for:addresses'がありますか? – maprihoda

+1

答えは「はい」です。人が持っている各アドレスに対して1つのperson_formが作成されます(永続化されているかどうか)。デバッグ(@ person.addresses)を試して、レンダリングページにヒットしたときに配列に3つのエントリがあることを確認してください。 –

+0

私の見解では、私の見解では<%= @ person.addresses.inspect%>と表示しましたが、実際には3つのアドレスが表示されます。何らかの理由でfields_forは私が構築したものを気にしません。私は何もビルドすることはできず、それでも1をレンダリングします。 – stackOverlord

答えて

1

あなたは、各ループの内側にあなたのfields_forブロックをラップし、fields_forの引数として各インスタンスを渡すことができます。たとえば:

<%= form_for @person do |person_form| %> 
    <% @person.addresses.each do |address| %> 
    <%= person_form.fields_for :addresses, address do |address_fields| %> 
     Street : <%= address_fields.text_field :street %> 
    <% end %> 
    <% end %> 
<% end %> 

代わりに、あなたはfields_forの引数としてコレクションを渡すことができますし、それが自動的に反復している:

<%= form_for @person do |person_form| %> 
    <%= person_form.fields_for :addresses, @person.addresses do |address_fields| %> 
    Street : <%= address_fields.text_field :street %> 
    <% end %> 
<% end %> 

http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for

+0

私は最初の提案を試み、それは仕事をします。しかし、私はまだ構文が清潔であるため、私の元のメソッドを動作させたいです。 – stackOverlord

+0

私は実際にどこから@address変数が来るのかわかりませんが、どこにでも定義していませんが、動作します。何らかの理由で2番目の提案は機能しません。 – stackOverlord

+0

これは、 "モデルアレイが通りに応答しません"というエラーをスローします。 – stackOverlord

0

まずレールを使用している、あなたはあなたのPersonモデルでaccepts_nested_attributes_for :addressesが必要になります。次に、buildを使用すると、実際にはビルドされますが、レコードは保存されません。この例を維持したい場合は、このようなもので上に行く:

3.times { @person.addresses.create } 
+2

'@ person.addresses.build'はフォームを表示したいだけで、アドレスを保存しないので正しいです(フォームにポストして保存します方法) – maprihoda

+0

それは私にはニュースです。常に 'build'は、この場合、' person_id'が既に設定されている未保存のレコードを返します。オブジェクトがアソシエーション配列に直接追加されるかどうかはわかりませんでした。 – tbuehlmann

+0

ええ、 'build'は、未保存のオブジェクトをメモリに作成し、自動的に関連付けから推定する外部キー(person_id)を設定します。これは、フォームをレンダリングするために必要なすべてです。つまり、フォームヘルパーは、メモリ内のどこかにぶら下がっている未保存のインスタンスであっても、インスタンスを正しくレンダリングする必要があります。 – maprihoda

1

フォームがOKに見える参照してください。ドキュメント(ri fields_for)によれば、Personモデルにaddressesリーダーとライターの両方のメソッドが必要です。 Person has_many:アドレスが記述されているので、既にreaderメソッドがあるので、writerメソッドが必要です。手動で作成するか(def addresses_attributes=(...))、accepts_nested_attributes_forでライターを定義することができます。

+0

accepts_nested_attributes_for:アドレスが定義されています。削除/追加は何も変更されていません。 – stackOverlord

関連する問題