> RELATED ARTICLE

* Quickly debugging form helpers

Sometimes you want to quickly see the output of helper methods, and constantly clicking refresh in your browser then viewing the page source can be tiresome. Instead, use the Rails console to check helpers are doing what you want them to. > More

Form Helpers Cheatsheet

Create forms, check boxes, radio buttons, select lists and more using Rails' built-in form helpers.

 

Table of Contents

1. form_for

form_for is used to easily manipulate HTML forms which are based upon ActiveRecord model objects:

<%= form_for(:customer, @customer, :url => { :controller => "customers", :action => "create" }, :html => { :multipart => true, :method => :put }) do |f| %>
  <%= f.text_field :age %> 
  <%= text_field "customer", :age %>
  <%= submit_tag %>
<% end %>
Table 1.1 form_for Parameters
KeyValuePurpose
:customer required:symbol or "string"The name of the ActiveRecord model object for all the fields in the form. All input fields will be prefixed with this. Rails will also look for an @instance_variable with the same name which should contain an instance of an existing or new ActiveRecord model object
@customer optionalObjectIf the @instance_variable containing the ActiveRecord model object is named differently, you can pass a variable containing the actual model object here
:url optional"string" or {hash}The URL to post the form to. Can take an explicit url as a string, or a hash in the same format as url_for
:html optional{hash}A {hash} of HTML attributes which will be added to the HTML <form> tag.
:method optional:symbolPass as part of the {hash} of HTML attributes. Can be :put, :post, :get or :delete

2. Parsing form data

When a form is submitted to a Rails application, the parameters are automatically translated by Rails into the params object which is accessible as a hash structure.

2.1. Simple query strings

Key/value pairs of your form’s input fields are stored simply as key/value pairs in the params hash, such as the id which is extracted by routing from the URL:

URLParametersHash constructed
/customers/1id=1{ :id => "1" }
/customers/1?color=redid=1&color=red{ :id => "1", :color => "red" }

2.2. Nesting

Square brackets [] are used to build more complex, nested structures:

Field helperParametersHash constructed
text_field :user, :nameuser[name]=David{ :user => { :name => "David" }
text_field "user[address]", :cityuser[address][city]=London{ :user => { :address => { :city => "London" }}}
text_field "user[address]", :streetuser[address][street]=Road{ :user => { :address => { :street => "Road" }}}

2.3. Multiple records

Using empty square brackets [] after the name of a model object, such as address[], will insert the id of the record you are editing into the input field, useful for editing multiple records on one form:

Field helperParametersHash constructed
text_field "address[]", :countryaddress[4][country]=England{ :address => { 4 => { :country => "England" }}}
text_field "address[]", :townaddress[4][town]=London{ :address => { 4 => { :town => "London" }}}

If the record is new and has no id, then upon submitting the form, Rails will convert the fields into an array of hashes in order of appearance.

text_field "address[]", :country 
text_field "address[]", :town
text_field "address[]", :country
text_field "address[]", :town

{ :address => [
    { :country => "England", :town => "London" },
    { :country => "Australia", :town => "Sydney" }
  ]
}

3. Example

3.1. Controller

def new
  @customer = Customer.new
  3.times do 
    @customer.addresses.build        
  end
end

3.2. View

<% form_for(@customer) do |f| %>
  <%= f.text_field :name %>
  <%= f.text_field :email %>
  <% @customer.addresses.each do |address| %>
    <% fields_for "customer[addresses][]", address do |fields| %>
      <%= fields.text_field :number %>
          <%= fields.text_field :street %>
  <% end %>
<% end %>

3.3. HTML

<form id="new_customer" class="new_customer" method="post" action="/customers">
<input type="text" size="30" name="customer[name]"/>
<input type="text" size="30" name="customer[email]"/>
<input type="text" size="30" name="customer[addresses][][number]"/>
<input type="text" size="30" name="customer[addresses][][street]"/>
<input type="text" size="30" name="customer[addresses][][number]"/>
<input type="text" size="30" name="customer[addresses][][street]"/>
<input type="text" size="30" name="customer[addresses][][number]"/>
<input type="text" size="30" name="customer[addresses][][street]"/>
<input type="submit" value="Create" name="commit"/>
</form>

3.4. params

params = {
  "customer" => { "name"=>"David Pettifer",
                  "email"=>"david.p@dizzy.co.uk",
                  "addresses"=> [
                    { "number"=>"31", "street"=>"High" },
                    { "number"=>"22", "street"=>"Brook" },
                    { "number"=>"16", "street"=>"Kents" }  ]
               } }

4. fields_for

fields_for creates a scope around a specific model object like form_for, but doesn’t create the form tags themselves, making fields_for suitable for specifying additional model objects in the same form. See the example.

5. RESTful form_for

When standard routes are used in a RESTful context, Rails will reflect upon the object passed to it and automatically build a form with the relevant RESTful URL depending on whether the form is wrapping a new record (create) or an existing record (update). Nested routes will require you to be more verbose. Standard routes

Standard routesnew record?methodURL
form_for(@customer)yesPOST/customers
form_for(@customer)noPUT/customers/1
Nested routesnew record?methodURL
form_for(@address, :url => customer_addresses_path(@customer))yesPOST/customers/1/addresses
form_for(@address, :url => customer_addresses_path(@customer))noPUT/customers/1/addresses/24

6. Input field helpers

f.error_messages_for
f.check_box :terms, { :class => 'check' }, "yes", "no"
f.file_field :image
f.hidden_field :id
f.label :customer, "Text for label"
f.password_field :password
f.radio_button :language, "French"
f.text_area :comment, :size => "20x30", :disabled => "disabled"
f.text_field :age, :size => "20", :class => "age_box"

7. Multipart form

7.1. View

<% form_for(@customer, :html => { :multipart => true }) do |f| %>
  <%= f.file_field :image_file %>
<%= submit_tag %>
<% end %>

7.2. Model

class Customer < ActiveRecord::Base
  def image_file=(uploaded_data)
    self.filename     = uploaded_data.original_filename
    self.image_data   = uploaded_data.read
    self.size         = uploaded_data.size
    self.content_type = uploaded_data.content_type        
  end
end
 

* COMMENTS

11 MONTHS AGO

Thanks

thanks for this nice article....

9 MONTHS AGO

Visual representation not necessary

Thanks for the cheatsheet! And here's some feedback: I think the "Visual representation of params" is unnecessary. The description of "params[]" just above it leaves no doubt about the organization of its content. So that space could be used for something else.

4 MONTHS AGO

Thanks

Thanks lot for the gr8 article

2 MONTHS AGO

Thanks

Phenomenal. This article helped me understand form helpers better.

2 MONTHS AGO

Great!

Great article. Thanks for the help.

ABOUT 1 MONTH AGO

Question

Hi Mr. Dizzy, I was wondering if you could help me with a related problem. My form, when using drop down menus, posts the following : aspectvalues[id] 11 aspectvalues[id] 15 How can i read these numbers from my controller pls? Thank you, Wim

17 MINUTES AGO

Excellent

This is excellent information for ruby on rails users.

7 MINUTES AGO

Excellent

This is really excellent information for rails users.