class ActionView::Helpers::FormBuilder

def fields_for(record_name, record_object = nil, fields_options = nil, &block)

to prevent fields_for from rendering it automatically.
hidden field is not needed and you can pass include_id: false
to store the ID of the record. There are circumstances where this
Note that fields_for will automatically generate a hidden field

<% end %>
...
<% end %>
...
Project #<%= project_fields.index %>
<%= person_form.fields_for :projects do |project_fields| %>
...
<%= form_for @person do |person_form| %>

is available in the FormBuilder object.
object in the array. For this purpose, the index method
When a collection is used you might want to know the index of each

<% end %>
...
<% end %>
Delete: <%= project_fields.check_box :_destroy %>
<%= person_form.fields_for :projects do |project_fields| %>
...
<%= form_for @person do |person_form| %>

(e.g. 1, '1', true, or 'true'):
parameter with a value that evaluates to +true+
attributes hash by adding a form element for the _destroy
This will allow you to specify which models to destroy in the

end
accepts_nested_attributes_for :projects, allow_destroy: true
has_many :projects
class Person < ActiveRecord::Base

option for +accepts_nested_attributes_for+:
form, you have to enable it first using the :allow_destroy
If you want to destroy any of the associated models through the

<% end %>
...
<% end %>
Name: <%= project_fields.text_field :name %>
<%= person_form.fields_for :projects, @active_projects do |project_fields| %>
...
<%= form_for @person do |person_form| %>

Or a collection to be used:

<% end %>
...
<% end %>
<% end %>
<% end %>
Name: <%= project_fields.text_field :name %>
<%= person_form.fields_for :projects, project do |project_fields| %>
<% if project.active? %>
<% @person.projects.each do |project| %>
...
<%= form_for @person do |person_form| %>

It's also possible to specify the instance to be used:

<% end %>
...
<% end %>
<% end %>
Name: <%= project_fields.text_field :name %>
<% if project_fields.object.active? %>
<%= person_form.fields_for :projects do |project_fields| %>
...
<%= form_for @person do |person_form| %>

collection:
the nested fields_for call will be repeated for each instance in the
This model can now be used with a nested fields_for. The block given to

end
accepts_nested_attributes_for :projects
has_many :projects
class Person < ActiveRecord::Base

+accepts_nested_attributes_for+ to define the writer method for you:
When projects is already an association on Person you can use

collection, and the correct indices to be set in the form markup.
required for fields_for to correctly identify :projects as a
Note that the projects_attributes= writer method is in fact

end
end
# Process the attributes hash
def projects_attributes=(attributes)

end
[@project1, @project2]
def projects
class Person

projects_attributes= writer method:
from the projects reader method and responds to the
Consider a Person class which returns an _array_ of Project instances

==== One-to-many

<% end %>
...
<% end %>
Delete: <%= address_fields.check_box :_destroy %>
...
<%= person_form.fields_for :address do |address_fields| %>
...
<%= form_for @person do |person_form| %>

model (e.g. 1, '1', true, or 'true'):
with a value that evaluates to +true+, you will destroy the associated
Now, when you use a form element with the _destroy parameter,

end
accepts_nested_attributes_for :address, allow_destroy: true
has_one :address
class Person < ActiveRecord::Base

+accepts_nested_attributes_for+:
to enable it first using the :allow_destroy option for
If you want to destroy the associated model through the form, you have

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

+accepts_nested_attributes_for+ to define the writer method for you:
When address is already an association on a Person you can use

<% end %>
...
<% end %>
Zip code: <%= address_fields.text_field :zip_code %>
Street : <%= address_fields.text_field :street %>
<%= person_form.fields_for :address do |address_fields| %>
...
<%= form_for @person do |person_form| %>

This model can now be used with a nested fields_for, like so:

end
end
# Process the attributes hash
def address_attributes=(attributes)

end
@address
def address
class Person

address_attributes= writer method:
address reader method and responds to the
Consider a Person class which returns a _single_ Address from the

==== One-to-one

or an _array_ of objects.
depends on whether the normal reader method returns a _single_ object
Whether a one-to-one or one-to-many style form builder will be yielded

address_attributes=.
writer for the association :address is called
defining a method with the proper name. For example: the attribute
with +accepts_nested_attributes_for+ in a model definition or by
association. The most common way of defining these writers is either
Nested attribute writers are normal setter methods named after an

the attributes of a parent object and its associations in one go.
for that attribute. This allows you to create forms that set or change
writer for a certain attribute, fields_for will yield a new scope
When the object belonging to the current scope has a nested attribute

=== Nested Attributes Examples

<% end %>
...
<% end %>
Admin?: <%= check_box_tag permission_fields.field_name(:admin), @person.permission[:admin] %>
<%= fields_for :permission, @person.permission, {} do |permission_fields| %>
...
<%= form_for @person do |person_form| %>

option Hash. To remove the ambiguity, explicitly pass an option Hash, even if empty.
name and value parameters are provided and the provided value has the shape of an
+fields_for+ tries to be smart about parameters, but it can be confused if both

FormOptionsHelper#collection_select and DateHelper#datetime_select.
DateHelper that are designed to work with an object as base, like
Note: This also works for the methods in FormOptionsHelper and

of class +Permission+, the field will still be named permission[admin].
_class_ of the model object, e.g. if @person.permission, is
and +fields_for+ will derive the required name of the field from the

<% end %>
Admin?: <%= permission_fields.check_box :admin %>
<%= fields_for @person.permission do |permission_fields| %>

name has been omitted) -
argument isn't a string or symbol +fields_for+ will realize that the
Alternatively, you can pass just the model object itself (if the first

field will reflect the value of that variable's attribute @permission.admin.
instance variable @permission, the initial state of the input
...in which case, if :permission also happens to be the name of an

<% end %>
Admin?: <%= permission_fields.check_box :admin %>
<%= fields_for :permission do |permission_fields| %>

object to +fields_for+ -
Often this can be simplified by passing just the name of the model

reflect the value of @person.permission.admin.
+admin+, the initial state of the checkbox when first displayed will
If @person.permission is an existing record with an attribute
value will appear in the controller as params[:permission][:admin].
tag with the +name+ attribute permission[admin], and the submitted
In this case, the checkbox field will be represented by an HTML +input+

<% end %>
<%= person_form.submit %>

<% end %>
Admin? : <%= permission_fields.check_box :admin %>
<%= fields_for :permission, @person.permission do |permission_fields| %>

Last name : <%= person_form.text_field :last_name %>
First name: <%= person_form.text_field :first_name %>
<%= form_for @person do |person_form| %>

object itself can be passed to the method separately -
both an object name (represented by either a symbol or string) and the
displayed. In order for both of these features to be specified independently,
default values are shown when the form the fields appear in is first
values appear within the +params+ hash in the controller) and what
a model object in two ways - how they are named (hence how submitted
generate fields associated with the model object. Fields may reflect
and within the block allows methods to be called on the builder to
a FormBuilder object associated with a particular model object to a block,
its method signature is slightly different. Like +form_for+, it yields
Although the usage and purpose of +fields_for+ is similar to +form_for+'s,

for specifying additional model objects in the same form.
doesn't create the form tags themselves. This makes fields_for suitable
Creates a scope around a specific model object like form_for, but
def fields_for(record_name, record_object = nil, fields_options = nil, &block)
  fields_options, record_object = record_object, nil if fields_options.nil? && record_object.is_a?(Hash) && record_object.extractable_options?
  fields_options ||= {}
  fields_options[:builder] ||= options[:builder]
  fields_options[:namespace] = options[:namespace]
  fields_options[:parent_builder] = self
  case record_name
  when String, Symbol
    if nested_attributes_association?(record_name)
      return fields_for_with_nested_attributes(record_name, record_object, fields_options, block)
    end
  else
    record_object = @template._object_for_form_builder(record_name)
    record_name   = model_name_from_record_or_class(record_object).param_key
  end
  object_name = @object_name
  index = if options.has_key?(:index)
    options[:index]
  elsif defined?(@auto_index)
    object_name = object_name.to_s.delete_suffix("[]")
    @auto_index
  end
  record_name = if index
    "#{object_name}[#{index}][#{record_name}]"
  elsif record_name.end_with?("[]")
    "#{object_name}[#{record_name[0..-3]}][#{record_object.id}]"
  else
    "#{object_name}[#{record_name}]"
  end
  fields_options[:child_index] = index
  @template.fields_for(record_name, record_object, fields_options, &block)
end