The Definitive Guide to accepts_nested_attributes_for a model in rails 3
by currentricity
accepts_nested_attributes_for is very useful when you want a single form to cater to multiple models. It gives you an easy way to include attributes from the associated tables and also to successfully save and delete objects.
Consider a scenario where ‘House’ has many ‘Rooms’ and has one ‘Address’. It also belongs to an ‘Owner’. Now suppose you want a single form for house which is able to present attributes for room[size], address[city,country] and user[fname,lname] and also is able to save it successfully. It entails the following steps.
1. In model house.rb
class House < ActiveRecord::Base belongs_to :owner has_one :address has_many :rooms accepts_nested_attributes_for :owner accepts_nested_attributes_for :address accepts_nested_attributes_for :rooms end
2. In house_controller.rb
you need to build the attributes. Notice the different methods used to build different associated models. It is a function of whether House has one or many of the other model. (Belongs to is a ‘one’ association). Also, I am only showing the parts which needs deviation from the general scaffolded code.
def new @house = House.new @house.rooms.build @house.build_address @house.build_owner respond_to do |format| format.html # new.html.erb format.json { render json: @house } end end
3. In view i.e. the house/_form.html.erb
add the attributes
<%= f.fields_for :address do |builder| %> <div class="field"> <%= builder.label :city %><br /> <%= builder.text_field :city %> </div> <% end -%> <%= f.fields_for :rooms do |builder| %> <div class="field"> <%= builder.label :size %><br /> <%= builder.number_field :size %> </div> <% end -%> <%= f.fields_for :owner do |builder| %> <div class="field"> <%= builder.label :fname %><br /> <%= builder.text_field :fname %> </div> <div class="field"> <%= builder.label :lname %><br /> <%= builder.text_field :lname %> </div> <% end -%>
4. Use
:allow_destroy => true
as a param to accepts_nested_attributes_for
to be able to successfully delete.
thank you… =D
thanks for this simple explanation…i will appreciate if you further go on to other similar concepts
Great article.
Thanks
thanks :)
This post is very helpful. Unfortunately, the low contrast styling doesn’t work for me at all. I made a version completely devoid of all pretense of style at http://kl1p.com/nested/2 (kl1p.com/nested/2)
Hey Ron,
Thanks for pointing that out. I have changed the theme of the blog and hopefully its much better now.
Yes, it did, thanks. (Just got back here from a different search — still quite useful!)
Reblogged this on Er. Ganesh Kunwar's and commented:
The Definitive Guide to accepts_nested_attributes_for a model in rails 3
Thank you, it helped me a lot :)
Glad it did.
Sadly you have not shown how you save the thing.
In my case I have the following problem: I have a Child that belongs_to a Parent, but can only be saved if it has a parent.
I can create a form that sets valid values for the Parent through nesting without a problem. But I can not save the thing, cause my Child is always invalid cause the parent has not been saved before.
How did you solve this for your House belongs_to Owner-problem?
This is great–but I’m running into a problem with uniqueness validations on my nested models.
For instance, let’s say you wanted your Owner model to be unique by fname/lname. If I want to associate a new house with an Owner that already exists in the db, is there a way around the fact that this form is going to try and create a brand new instance of Owner?