<img src=“https://secure.travis-ci.org/ryanb/nested_form.png?branch=master” alt=“Build Status” />
This is a Rails gem for conveniently manage multiple nested models in a single form. It does so in an unobtrusive way through jQuery or Prototype.
This gem only works with Rails 3. See the rails2 branch for a plugin to work in Rails 2.
An example project showing how this works is available in the complex-nested-forms/nested_form branch.
Add it to your Gemfile then run bundle
to install it.
gem "nested_form"
And then add it to the Asset Pipeline in the appication.js file:
//= require jquery_nested_form
If you do not use the asset pipeline, run this generator to create the JavaScript file.
rails g nested_form:install
You can then include the generated JavaScript in your layout.
<%= javascript_include_tag :defaults, "nested_form" %>
Imagine you have a Project
model that has_many :tasks
. To be able to use this gem, you’ll need to add accepts_nested_attributes_for :tasks
to your Project model. If you wish to allow the nested objects to be destroyed, then add the :allow_destroy => true
option to that declaration. If you don’t have the accepts_nested_attributes_for :tasks
you’ll get a Missing Block Error. See the accepts_nested_attributes_for documentation for details on all available options.
This will create a tasks_attributes=
method, so you may need to add it to the attr_accessible
array. (attr_accessible :tasks_attributes
)
Then use the nested_form_for
helper method to enable the nesting.
<%= nested_form_for @project do |f| %>
You will then be able to use link_to_add
and link_to_remove
helper methods on the form builder in combination with fields_for to dynamically add/remove nested records.
<%= f.fields_for :tasks do |task_form| %> <%= task_form.text_field :name %> <%= task_form.link_to_remove "Remove this task" %> <% end %> <p><%= f.link_to_add "Add a task", :tasks %></p>
Use simple_nested_form_for
or semantic_nested_form_for
for SimpleForm and Formtastic support respectively. This is feature is not yet in a Gem release but is in the Git repo.
It is often desirable to move the nested fields into a partial to keep things organized. If you don’t supply a block to fields_for it will look for a partial and use that.
<%= f.fields_for :tasks %>
In this case it will look for a partial called “task_fields” and pass the form builder as an f
variable to it.
If you are using jQuery, nested:fieldAdded
and nested:fieldRemoved
events are triggered on the form
element after adding and removing fields.
You can override default behavior of inserting new subforms into your form. For example:
window.nestedFormEvents.insertFields = function(content, assoc, link) { return $(link).closest('form').find(assoc + '_fields').append($(content)); }
Unfortunately I have not had time to actively work on this project recently. If you find a critical issue where it does not work as documented please ping me on Twitter and I’ll take a look.
This gem was originally based on the solution by Tim Riley in his complex-form-examples fork.
Thank you Andrew Manshin for the Rails 3 transition, Andrea Singh for converting to a gem and Peter Giacomo Lombardo for Prototype support.
Andrea also wrote a great blog post on the internal workings of this gem.
Thanks Pavel Forkert for the SimpleForm and Formtastic support.