Nested forms in Rails 2.3

Posted in rails by elisehuard on April 19, 2009

I’ve had the opportunity to use the new and improved nested forms in Rails. When you have a has_many relationship, you can add, modify or delete the many instances corresponding to your one instance.
Well, they work. I can even go one further: they work when you have nested forms in nested forms. I’ve used things like:

<% form_for :library, :url => library_path(@library), :html => {:method => :put} do |f| %>
  <%= f.text_field :name %>
  <% f.fields_for :books do |b| %>
    <%= b.text_field :author %>
    <% b.fields_for :chapters do |c| %>
      <%= c.text_field :title %>
    <% end %>
  <% end %>
<% end %>

You have to have initialized the objects in question in your controller (using build), or they need to exist already to appear in the form.
But i was actually surprised that it just worked, without further ado ! Very decent code in that form_helper, congrats to the developers.

One thing i find slightly less well done, is that when you want to step outside of the Rails magic to make some slightly more involved markup, you cannot retrieve the index the fields_for generates. I worked around this by doing something ugly but effective in the view:
<% i  = 0 %>
<% f.fields_for :books do |b| %>>
  <% i += 1 %>
<% end %>

And using i as the index in the markup.

Tagged with: , ,

3 Responses

Subscribe to comments with RSS.

  1. hgujral said, on November 18, 2009 at 9:09 pm

    This is a great tip but I don’t seem to be able to get to a specific nested variable using this variable as an array index.

    For example I have select tags with grouped_options_for_select for the fields_for nested entity and therefore I have a need to define the current selected key for each select tag:


    I don’t seem to be able to do: grouped_options_for_select (@items,
    @invoice.invoice_line_items[i].item, “Please select…”) where “i” is the variable defined.

    Any ideas?

  2. hgujral said, on November 18, 2009 at 9:11 pm

    OK my previous post trimmed the select tags markup I had.. but I guess you get the idea…

  3. elisehuard said, on November 21, 2009 at 1:58 pm

    hi hgujral,
    the idea is to reproduce the markup that would be automagically produced.
    You type in the html as is, and you use (i assume item is the attribute of your line_item model):
    for id: invoice_line_items_attributes_<%= i %>_item
    for name: invoice[line_items_attributes][<%= i %>][item]
    you can make a html select tag using those two attributes, and put your grouped_options_for_select inside.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: