views:

25

answers:

1

Somehow, I was under impression that accepts_nested_attributes_for will let me populate child object through parent:

person.update_attributes person_hash

but in practice I ended up doing this:

person.address.update_attributes person_hash[:address]
person_hash.delete :address
person.update_attributes person_hash

Now, http://guides.rubyonrails.org mentions accepts_nested_attributes_for only indirectly and API documentation for this method is also quite cryptic.

1) Could someone show basic use-case for accepts_nested_attributes_for? I mean, I understand how it's declared, I'm confused about the difference it makes.

2) Is the way I populate nested object the 'right' one in rails, or there's something more 'elegant'?

Thanks!

update
Model, for clarity

class Person < ActiveRecord::Base
  has_one :address
  accepts_nested_attributes_for :address
end

update2, for j.
Form declaration goes like this

<% fields_for "people", person, :index => person.id do |person_form| %>
  ... 
  <% person_form.fields_for person.address do |address_form| %>
    <%= address_form.text_field :street %>
  <% end %>
  ...
<% end %>

But it gives me html names like people[66][address][street] and not people[66][address_attributes][street]

+1  A: 

With accepts_nested_attributes_for you can do the following:

# example from railsapi.com
# view
<% form_for @person, :url => { :action => "create" } do |person_form| %>
   Name: <%= person_form.text_field :name %>
   ...
   <% person_form.fields_for :address do |address_fields| %>
     Street  : <%= address_fields.text_field :street %>
     Zip code: <%= address_fields.text_field :zip_code %>
   <% end %>
<% end %>

With this, your parameters will look like

params = { 
   :person => { 
      :name => 'Jack',
      :address_attributes => { :street => 'Street', :zip_code => '11111' } 
   }
}

and you're able to create a person and the related address just using

@person = Person.create(params)

For more information, railsapi.com. I hope it helps.

Edit

I have no idea why your params look like this :/ But using

#person.address.update_attributes person_hash.delete(:address) OR
person.address.update_attributes person_hash[:address]
person_hash.delete :address

person.update_attributes person_hash

is not wrong. Just could be done with more elegant code, as you said.

j.
Actually, I declare form in the same way, but I get parameter names in style "people[66][address][street]" and not "people[66][address_attributes][street]"
Nikita Rybak
updated question with form declaration too. Thanks!
Nikita Rybak