module ActionView::Helpers::FormHelper

def apply_form_for_options!(object_or_array, options) #:nodoc:

:nodoc:
def apply_form_for_options!(object_or_array, options) #:nodoc:
  object = object_or_array.is_a?(Array) ? object_or_array.last : object_or_array
  object = convert_to_model(object)
  as = options[:as]
  action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :put] : [:new, :post]
  options[:html].reverse_merge!(
    :class  => as ? "#{action}_#{as}" : dom_class(object, action),
    :id     => as ? "#{action}_#{as}" : [options[:namespace], dom_id(object, action)].compact.join("_").presence,
    :method => method
  )
  options[:url] ||= polymorphic_path(object_or_array, :format => options.delete(:format))
end

def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")


#
# =>
check_box("eula", "accepted", { :class => 'eula_check' }, "yes", "no")

#
# =>
check_box("puppy", "gooddog", {}, "yes", "no")
# Let's say that @puppy.gooddog is "no":

#
# =>
check_box("post", "validated")
# Let's say that @post.validated? is 1:
==== Examples

hashes instead of arrays.
In that case it is preferable to either use +check_box_tag+ or to use

get an extra ghost item with only that attribute, assigned to "0".
the elements of the array. For each item with a checked check box you
because parameter name repetition is precisely what Rails seeks to distinguish

<% end %>
...
<%= form.check_box :paid %>
<%= fields_for "project[invoice_attributes][]", invoice, :index => nil do |form| %>

within an array-like parameter, as in
Unfortunately that workaround does not work when the check box goes

key in the query string, that works for ordinary forms.
form, and parameters extraction gets the last occurrence of any repeated
says key/value pairs have to be sent in the same order they appear in the
the check box is unchecked), or both fields. Since the HTML specification
This way, the client either sends only the hidden field (representing

attributes mimic an unchecked check box.
the very check box. The hidden field has the same name and its
To prevent this the helper generates an auxiliary hidden field before

wouldn't update the flag.

@invoice.update_attributes(params[:invoice])

any mass-assignment idiom like
invoice the user unchecks its check box, no +paid+ parameter is sent. So,
if an +Invoice+ model has a +paid+ flag, and in the form that edits a paid
thus web browsers do not send them. Unfortunately this introduces a gotcha:
The HTML specification says unchecked check boxes are not successful, and

==== Gotcha

while the default +unchecked_value+ is set to 0 which is convenient for boolean values.
Additional options on the input tag can be passed as a hash with +options+. The +checked_value+ defaults to 1
It's intended that +method+ returns an integer and if that integer is above zero, then the checkbox is checked.
assigned to the template (identified by +object+). This object must be an instance object (@object) and not a local object.
Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object
def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_check_box_tag(options, checked_value, unchecked_value)
end

def convert_to_model(object)

Converts the given object to an ActiveModel compliant one.
def convert_to_model(object)
  object.respond_to?(:to_model) ? object.to_model : object
end

def default_form_builder

def default_form_builder
  builder = ActionView::Base.default_form_builder
  builder.respond_to?(:constantize) ? builder.constantize : builder
end

def email_field(object_name, method, options = {})


# =>
email_field("user", "address")

Returns a text_field of type "email".
def email_field(object_name, method, options = {})
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("email", options)
end

def fields_for(record_name, record_object = nil, options = {}, &block)

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

(eg. 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
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

<% 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 (eg. 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

FormOptionHelper#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 FormOptionHelper and

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

...or if you don't have an object, just a name of the parameter:

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

parameter, like a Client that acts as a Person:
...or if you have an object that needs to be represented as a different

<% end %>
<%= f.submit %>

<% end %>
Admin? : <%= permission_fields.check_box :admin %>
<%= fields_for @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| %>

=== Generic Examples

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, options = {}, &block)
  builder = instantiate_builder(record_name, record_object, options, &block)
  output = capture(builder, &block)
  output.concat builder.hidden_field(:id) if output && options[:hidden_field_id] && !builder.emitted_hidden_id?
  output
end

def file_field(object_name, method, options = {})


# =>
file_field(:attachment, :file, :class => 'file_input')

# =>
file_field(:post, :attached, :accept => 'text/html')

# =>
file_field(:user, :avatar)
==== Examples

Using this method inside a +form_for+ block will set the enclosing form's encoding to multipart/form-data.

shown.
hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
Returns a file upload input tag tailored for accessing a specified attribute (identified by +method+) on an object
def file_field(object_name, method, options = {})
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("file", options.update({:size => nil}))
end

def form_for(record, options = {}, &proc)

<% end %>
...
<%= form_for @invoice, :url => external_url, :authenticity_token => false do |f|

If you don't want to an authenticity token field be rendered at all just pass false:

<% end %>
...
<%= form_for @invoice, :url => external_url, :authenticity_token => 'external_token' do |f|

To set an authenticity token you need to pass an :authenticity_token parameter

without it, for example when you submit data to a payment gateway number and types of fields could be limited.
When you build forms to external resources sometimes you need to set an authenticity token or just render a form

=== Form to external resources

FormTagHelper#form_tag.
If you don't need to attach a form to a model instance, then check out

end
form_for(record_or_name_or_array, *(args << options.merge(:builder => LabellingFormBuilder)), &proc)
options = args.extract_options!
def labelled_form_for(record_or_name_or_array, *args, &proc)

could do something like the following:
In many cases you will want to wrap the above in another helper, so you

of a nested fields_for call, unless it's explicitly set.
The custom FormBuilder class is automatically merged with the options

labelling_form.
variable referencing the form builder is called
The rendered template is people/_labelling_form and the local

<%= render f %>

In this case, if you use this:

<% end %>
<%= f.submit %>
<%= f.check_box :admin %>
<%= f.text_area :biography %>
<%= f.text_field :last_name %>
<%= f.text_field :first_name %>
<%= form_for @person, :url => { :action => "create" }, :builder => LabellingFormBuilder do |f| %>

automatically add labels to form inputs.
custom builder. For example, let's say you made a helper to
FormBuilder and override or define some more helpers, then use your
You can also build forms using a customized FormBuilder class. Subclass

=== Customized form builders

<% end %>
<% end %>
...
<% f.fields_for(:comments, :include_id => false) do |cf| %>
<%= form_for(@post) do |f| %>

Example:

thus there is no primary key for comments.
In the following example the Post model has many Comments stored within it in a NoSQL database,

to disable the hidden id.
Some ORM systems do not use IDs on nested models so in this case you want to be able
This is used to maintain the correlation between the form data and its associated model.
The form_for method automatically includes the model id as a hidden field in the form.

=== Removing hidden model id's


...





The HTML generated for this would be:

<% end %>
...
<%= form_for(@post, :remote => true) do |f| %>

Example:

a regular submission as viewed by the receiving side (all elements available in params).
Even though it's using JavaScript to serialize the form elements, the form submission will work just like
POST arrangement, but ultimately the behavior is the choice of the JavaScript driver implementor.
behavior. The expected default behavior is an XMLHttpRequest in the background instead of the regular
in the options hash creates a form that will allow the unobtrusive JavaScript drivers to modify its

:remote => true

Specifying:

=== Unobtrusive JavaScript

to interpret.
form will be set to POST and a hidden input called _method will carry the intended verb for the server
in the options hash. If the verb is not GET or POST, which are natively supported by HTML forms, the

:method => (:get|:post|:put|:delete)

You can force the form to use the full array of HTTP verbs by setting

=== Setting the method

@comment = Comment.new.
Where @document = Document.find(params[:id]) and

<% end %>
...
<%= form_for([@document, @comment]) do |f| %>

to the document given that the routes are set correctly:
If your resource has associations defined, for example, you want to add comments

<% end %>
...
<%= form_for([:admin, @post]) do |f| %>

For namespaced routes, like +admin_post_url+:

<% end %>
...
<%= form_for(@person, :as => :client) do |f| %>

parameter, like a Person that acts as a Client:
If you have an object that needs to be represented as a different

<% end %>
...
<%= form_for(@post, :format => :json) do |f| %>

You can also set the answer format, like this:

<% end %>
...
<%= form_for(@post, :url => super_posts_path) do |f| %>

You can also overwrite the individual conventions, like this:

<% end %>
...
<%= form_for @post, :as => :post, :url => posts_path, :html => { :class => "new_post", :id => "new_post" } do |f| %>

is equivalent to something like:

<% end %>
...
<%= form_for(Post.new) do |f| %>

And for new records

<% end %>
...
<%= form_for @post, :as => :post, :url => post_path(@post), :method => :put, :html => { :class => "edit_post", :id => "edit_post_45" } do |f| %>

is equivalent to something like:

<% end %>
...
<%= form_for @post do |f| %>

For example, if @post is an existing record you want to edit

preferred way to use +form_for+ nowadays.
the conventions and named routes of that approach. This is the
call, you can rely on automated resource identification, which will use
As we said above, in addition to manually configuring the +form_for+

=== Resource-oriented style

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

<% end %>
<%= f.submit %>
Admin? : <%= check_box_tag "person[admin]", @person.company.admin? %>
Biography : <%= text_area :person, :biography %>
Last name : <%= f.text_field :last_name %>
First name: <%= f.text_field :first_name %>
<%= form_for @person do |f| %>

from FormTagHelper. For example:
possible to use both the stand-alone FormHelper methods and methods
Also note that +form_for+ doesn't create an exclusive scope. It's still

* :html - Optional HTML attributes for the form tag.
with underscore on the generated HTML id.
id attributes on form elements. The namespace attribute will be prefixed
* :namespace - A namespace for your form to ensure uniqueness of
here a named route directly as well. Defaults to the current action.
fields you pass to +url_for+ or +link_to+. In particular you may pass
* :url - The URL the form is submitted to. It takes the same

optional hash of options:
The rightmost argument to +form_for+ is an

<%= text_field :person, :first_name %>

gets expanded to

<%= f.text_field :first_name %>

model. Thus, the idea is that
The form builder acts as a regular form helper that somehow carries the

object the form is about.
There, the argument is a symbol or string with the name of the

<% end %>
<%= f.submit %>
Admin? : <%= f.check_box :admin %>

Biography : <%= f.text_area :biography %>

Last name : <%= f.text_field :last_name %>

First name: <%= f.text_field :first_name %>

<%= form_for :person do |f| %>

model:
The generic way to call +form_for+ yields a form builder around a

=== Generic form_for

based upon.
it does we need to dig first into the alternative generic usage it is
parameters based on introspection on the record, but to understand what
There, +form_for+ is able to generate the rest of RESTful form

<% end %>
<%= f.submit %>
<%= f.text_field :author %>

<%= f.label :author, 'Author' %>:
<%= f.text_field :version %>

<%= f.label :version, 'Version' %>:
<%= form_for @offer do |f| %>

like this:
Rails provides succinct resource-oriented form generation with +form_for+

as a base for questioning about values for the fields.
Creates a form and a scope around a specific model object that is used
def form_for(record, options = {}, &proc)
  raise ArgumentError, "Missing block" unless block_given?
  options[:html] ||= {}
  case record
  when String, Symbol
    object_name = record
    object      = nil
  else
    object      = record.is_a?(Array) ? record.last : record
    object_name = options[:as] || ActiveModel::Naming.param_key(object)
    apply_form_for_options!(record, options)
  end
  options[:html][:remote] = options.delete(:remote) if options.has_key?(:remote)
  options[:html][:method] = options.delete(:method) if options.has_key?(:method)
  options[:html][:authenticity_token] = options.delete(:authenticity_token)
  builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
  fields_for = fields_for(object_name, object, options, &proc)
  default_options = builder.multipart? ? { :multipart => true } : {}
  output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html)))
  output << fields_for
  output.safe_concat('</form>')
end

def hidden_field(object_name, method, options = {})

# =>
hidden_field(:user, :token)

# =>
hidden_field(:post, :tag_list)

# =>
hidden_field(:signup, :pass_confirm)
==== Examples

shown.
hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
Returns a hidden input tag tailored for accessing a specified attribute (identified by +method+) on an object
def hidden_field(object_name, method, options = {})
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("hidden", options)
end

def instantiate_builder(record_name, record_object, options, &block)

def instantiate_builder(record_name, record_object, options, &block)
  case record_name
  when String, Symbol
    object = record_object
    object_name = record_name
  else
    object = record_name
    object_name = ActiveModel::Naming.param_key(object)
  end
  builder = options[:builder] || default_form_builder
  builder.new(object_name, object, self, options, block)
end

def label(object_name, method, content_or_options = nil, options = nil, &block)

end
'Accept Terms.'.html_safe
label(:post, :terms) do

# =>
label(:post, :privacy, "Public Post", :value => "public")

# =>
label(:post, :title, "A short title", :class => "title_label")

# =>
label(:post, :title, "A short title")

# =>
label(:post, :cost)

cost: "Total cost"
post:
attributes:
activerecord:

(if you are using ActiveRecord):
Localization can also be based purely on the translation of the attribute-name

# =>
label(:post, :body)

Which then will result in

body: "Write your entire text here"
post:
label:
helpers:

For example you can define the following in your locale (e.g. en.yml)
You can localize your labels based on model and attribute names.

# =>
label(:post, :title)
==== Examples

target labels for radio_button tags (where the value is used in the ID of the input tag).
onto the HTML as an HTML element attribute as in the example shown, except for the :value option, which is designed to
Additional options on the label tag can be passed as a hash with +options+. These options will be tagged
is found in the current I18n locale (through helpers.label..) or you specify it explicitly.
assigned to the template (identified by +object+). The text of label will default to the attribute name unless a translation
Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object
def label(object_name, method, content_or_options = nil, options = nil, &block)
  options ||= {}
  content_is_options = content_or_options.is_a?(Hash)
  if content_is_options || block_given?
    options.merge!(content_or_options) if content_is_options
    text = nil
  else
    text = content_or_options
  end
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_label_tag(text, options, &block)
end

def number_field(object_name, method, options = {})

* Accepts same options as number_field_tag
==== Options

Returns an input tag of type "number".
def number_field(object_name, method, options = {})
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("number", options)
end

def password_field(object_name, method, options = {})


# =>
password_field(:account, :pin, :size => 20, :class => 'form_input')

# =>
password_field(:user, :password, :onchange => "if $('user[password]').length > 30 { alert('Your password needs to be shorter!'); }")

# =>
password_field(:account, :secret, :class => "form_input", :value => @account.secret)

# =>
password_field(:login, :pass, :size => 20)
==== Examples

shown.
hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
Returns an input tag of the "password" type tailored for accessing a specified attribute (identified by +method+) on an object
def password_field(object_name, method, options = {})
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("password", { :value => nil }.merge!(options))
end

def radio_button(object_name, method, tag_value, options = {})

#
# =>
radio_button("user", "receive_newsletter", "no")
radio_button("user", "receive_newsletter", "yes")

#
# =>
radio_button("post", "category", "java")
radio_button("post", "category", "rails")
# Let's say that @post.category returns "rails":
==== Examples

+options+ hash. You may pass HTML options there as well.
To force the radio button to be checked pass :checked => true in the

radio button will be checked.
assigned to the template (identified by +object+). If the current value of +method+ is +tag_value+ the
Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object
def radio_button(object_name, method, tag_value, options = {})
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_radio_button_tag(tag_value, options)
end

def range_field(object_name, method, options = {})

* Accepts same options as range_field_tag
==== Options

Returns an input tag of type "range".
def range_field(object_name, method, options = {})
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("range", options)
end

def search_field(object_name, method, options = {})


# =>
search_field(:user, :name, :autosave => true, :onsearch => true)
# =>
search_field(:user, :name, :autosave => false, :onsearch => true)
# =>
search_field(:user, :name, :onsearch => true)
# =>
search_field(:user, :name, :autosave => true)
# Assume request.host returns "www.example.com"
# =>
search_field(:user, :name, :results => 3)
# =>
search_field(:user, :name, :autosave => false)
# =>
search_field(:user, :name)

==== Examples

some browsers.
assigned to the template (identified by +object_name+). Inputs of type "search" may be styled differently by
Returns an input of type "search" for accessing a specified attribute (identified by +method+) on an object
def search_field(object_name, method, options = {})
  options = options.stringify_keys
  if options["autosave"]
    if options["autosave"] == true
      options["autosave"] = request.host.split(".").reverse.join(".")
    end
    options["results"] ||= 10
  end
  if options["onsearch"]
    options["incremental"] = true unless options.has_key?("incremental")
  end
  InstanceTag.new(object_name, method, self, options.delete("object")).to_input_field_tag("search", options)
end

def telephone_field(object_name, method, options = {})


# =>
telephone_field("user", "phone")

Returns a text_field of type "tel".
def telephone_field(object_name, method, options = {})
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("tel", options)
end

def text_area(object_name, method, options = {})

#
# #{@entry.body}
# =>
# #{@application.notes}
# =>
# #{@comment.text}
# =>
# #{@post.body}
# =>