Absolute Moron's Guide to Forms in Rails, Part 3 11
Pretzels anyone?
Today we continue our tour of forms in Rails. Parts one and two established these key ideas:
- Your html.erb templates generate raw HTML form code for the browser.
- Forms that target a model should use
form_forto make life easy. - Your
routes.rbis used by Rails to transform HTTP requests from the browser into a Ruby hash that’s always calledparamsinside your controller. - The
paramshash is your bridge between the browser and your controller. - If you follow simple conventions for the
nameattribute of your HTML controls, Rails will automatically populate theparamshash in ways that make it easy to spoon-feed your models with data.
Let’s continue by learning how to add a check box onto our form.
In Part 1 our form contained a textbox so that we could create a new flight given a flight number. Let’s also indicate if there will be meal service on the flight.
Adding a new column to the Flights table
First we need to add a new attribute to our Flight model. We have two choices for altering the table. We can modify our existing migration file and run the migrations from the beginning (rake db:migrate:reset), but that’s not going to help us if we’ve already deployed this app to production. Let’s say that the app is already deployed, and so we will go ahead and create a new migration file:
script/generate migration AddMealToFlight
or for those on Windows
ruby script\generate migration AddMealToFlight
Open the new migration file and you should have something like this:
class AddMealToFlight < ActiveRecord::Migration def self.up end def self.down end end
Add some code inside the up and down methods to add a boolean column to our table:
def self.up add_column :flights, :meal, :boolean, :default => false end def self.down remove_column :flights, :meal end
We’ve added a boolean column named meal which will, of course, default to false, because nowadays it seems only flights longer than two days come with free meals.
Finally, update the database:
rake db:migrate
Rails does a nifty thing with boolean columns: it supports the Ruby question mark convention for object attributes that return a boolean Ruby value. Open up your Rails console to see what I mean:
script/console Loading development environment (Rails 2.0.2) >> f = Flight.find(1) => #<Flight id: 1, number: "123", created_at: "2008-04-05 20:05:24", updated_at: "2008-04-05 20:05:24", meal: false> >> f.meal? => false
Me Want GUI
Now that we have our new column, let’s add a checkbox to our form so that we can set the meal value when we create the flight.
Open up the new.html.erb template again, and use the form builder object to add a checkbox:
<p>
<%= f.check_box :meal %><b>Meal Service</b>
</p>
Navigate to the form in your browser:

Let’s take a quick look at the actual HTML that got generated. You’ll see some new HTML inside our form:
<p> <input id="flight_meal" name="flight[meal]" type="checkbox" value="1" /> <input name="flight[meal]" type="hidden" value="0" /><b>Meal Service</b> </p>
The first <input> control is our checkbox. Notice again how it uses the “model[attribute]” convention to help populate the params hash for later processing. If the checkbox is selected, the browser will send the value “1”.
If the checkbox isn’t selected, browsers won’t send “0”. In fact, they won’t send anything at all! This is a problem, because it means that if we were editing this flight, and you unchecked the box to turn off meal service, we would never know it, because the flight[meal] value would not exist in the params hash.
To get around this, the check_box method we used automatically inserts that second, hidden input tag, with the same name but a value of zero. If the checkbox is not checked, this input value will be sent by the browser and our Rails code will update the model accordingly.
Go ahead and check the box, and then click the Create button. You’ll create a new flight, and this time the meal column will have the value true. We can learn how to use the new meal? attribute by opening up the Rails console again and finding our new flight:
>> f = Flight.find_by_number '987'
=> #<Flight id: 2, number: "987", created_at: "2008-04-05 20:24:21", updated_at: "2008-04-05 20:24:21", meal: true>
>> f.meal?
=> true
Ta da! A checkbox that’s hooked up to the meal column, just like we hooked up our textbox to the number column last time. .NET readers may begin to see that form_for is how we do “data binding” in Rails.
Radio Radio
Next time, we’ll be adding some radio buttons to our form. In the meantime, if you have comments or questions on what we’ve done so far, leave us a comment below.




What browser is that a screen shot of?
@Justin: Looks like firefox 3 for the mac. Beta 5 came out last Wednesday (I think)
http://www.mozilla.com/en-US/firefox/3.0b5/whatsnew/
@Justin
It's the Firefox 3 beta.
ok - people enough with the browser comments and questions... give the man some props for the quality tutorials he's producing, not for the browser that someone else made.
You da man Jeff!
ps. the browser is nice.
Thanks, Jack. I'm glad somebody saw something other than the screenshots :-)
(or is that just you again, Mom?)
Therefore, the pure employment of our knowledge is what first gives rise to the paralogisms of pure reason, since none of our sense perceptions are disjunctive.
The fundamental form of this universal synthesis (if we maintain this attitude) needs to be criticized with regard to its validity and range, before it can be used for the purposes of a radical grounding of an infinite horizon of approximations by orienting scientific evidence according to accured insights.
I’m new to rails and have to implement some kind of user management for this platform we’re developing. I’ve been going through the REST-Tutorials and now these and I have to say: It’s been very informative and so much of a fun read on top of it! You writing style really makes me crack up (to the point where my co-workers are wondering what I’m chuckling about). Thank you very much and keep up the good work! I’m already looking forward to reading the rest of these posts and the Capistrano-Chapter.
(btw this ain’t yo Mama!)
Hey, this tutorial and the REST tutorial is EXACTLY what people need to be reading before jumping into rails. Helps you understand the fundamentals of the framework. Thanks again.
Okay I have a question. I am trying to add a check box to the form for a model just like this tutorial. However, I don’t need to store the flag in the back-end nor in the model. So how can I get the check box value in that case when there is no auto magical link from form param to model?? I tried and keep failing. Frustrating because this should be simply and work the first time! :)
phil: have you tried a plain check_box_tag ? That will generate a “bare” checkbox without any associated model. See the docs here