The accepts_nested_attributes_for Handbook
Rails has accepts_nested_attributes_for
which helps when building forms that combine a parent and their related models. Unfortunately, I normally get it wrong and spend far too long tracking down why it isn’t working. Hopefully this will help reduce that time in future.
Gotchas
- If you’re using
update_attributes
then:foo_attributes
must beattr_accessible
. - Pass in the parent object instance to
form_for
, then useform.fields_for
inside that for the related models.
Example
Models
class Library
attr_accessible :name, :books_attributes
has_many :books, :inverse_of => :library
accepts_nested_attributes_for :books
end
class Book
attr_accessible :title, :author
belongs_to :library, :inverse_of => :books
end
View
<%= form_for @library do |form| %>
Library name: <%= form.text_field :name %>
<h2>Books</h2>
<%= form.fields_for :books do |book_form| %>
<p>
Title: <%= book_form.text_field :title %>
Author: <%= book_form.text_field :author %>
</p>
<% end %>
<% end %>
Controller
class LibraryController < ApplicationController
def update
@library = Library.find(params[:id])
# This updates the books as well
if @library.update_attributes(params[:library])
redirect_to :show
else
redirect_to :edit
end
end
end