In this seventh part of a multi-part series on the Action Pack library for Rails, you'll learn how to create a registration form using form helpers. This article is excerpted from chapter six of the book Beginning Rails: From Novice to Professional, written by Jeffery Allan Hardy, Cloves Carneiro Jr. and Hampton Catlin (Apress; ISBN: 1590596862).
Creating an Action Pack Registration Form - Using Form Helpers (Page 2 of 2 )
One of the best things about working with templates in Rails is the presence of helpers. Rails comes with a bunch of helper methods for taking the tedium out of generating those bits of HTML that your views need. And let’s face it, nothing is more of a drag to build than HTML forms. Fortunately, Rails understands the plight of the web developer all too well, and provides a suite of easy ways to build forms.
Two basic varieties of form helpers are available:
FormHelper: Active Record-aware tag helpers for creating forms that hook into models.
FormTagHelper: Helpers that just output tags. They are not integrated with Active Record. The names of these helpers are suffixed with_tag.
TheFormHelpertype is aware of Active Record objects assigned to the template; theFormTagHelper(note theTag) type is not. The advantage of the Active Record-aware,FormHelper, helpers is that they know how to populate themselves with data and can automatically be highlighted in the event of validation errors from the model. But not every form element you’ll make corresponds directly to a model attribute. That’s where theFormTagHelpergroup comes in handy. These have no special relationship with Active Record; they just output form tags.
In our registration form (Listing 6-3) we used four helpers:form_tag,text_field,password_field, andsubmit_tag.
Theform_taghelper is of theFormTagHelpervariety. It simply creates an HTML form tag and places everything in thedo..endblock inside the resulting form. By default, forms use the HTTPPOSTmethod. If you want to use a different method, you need to specify it manually using the:methodoption (for example,:method => :get).
GET VS. POST
The HTTP protocol defines several request methods, the most popular of which are GET and POST. Both are methods for requesting a web page; the difference is in how the request is sent. GET is the simpler of the two. It includes all the information about the request as part of the URL. POST sends information invisibly, which is to say, as part of the request header and not part of the URL. So, you can’t type a POST request into your browser’s location bar. Every time you request a web page via the location bar in your browser, you’re using GET. When you submit a form, say to register on a web site, the form is submitted via a POST.
So, how do you know when to use which? The best way to think of this is to consider GET a read method. It should never do anything "destructive," as in modifying a database record. POST, on the other hand, can be thought of as a write method. When you need to update or delete data, use POST.
Thetext_fieldhelper is of theFormHelpervariety, meaning that it corresponds to Active Record objects. It creates an HTMLinputtag whose type is set to"text"and assigns it a name and an ID that match the given object and method (userandloginin our example). Here’s what the rendered output looks like:
Thepassword_fieldhelper is also of theFormHelpervariety. It is the same astext_field, except its type is set to"password". Thepassword type ensures that the input is masked (replaced by asterisks) to prevent anyone from seeing the password as it’s entered. Here’s what the HTML output looks like:
Thesubmit_taghelper is aFormTagHelperthat creates aninput element whose type is set to"submit". It accepts the name of the submit button as its first argument. Since this is aFormTagHelper, it doesn’t hook into Active Record. It just spits out a tag.
All these helpers (and to be sure, most helpers in Rails) accept a hash of options as their last argument to customize the resulting HTML. For example, if we wanted to give our login field a class oflarge, we would write the following:
You can pass arbitrary options in this way, all of which will end up as attributes on the resulting tag. For example, if you wanted to apply an in-linestyleattribute, you could use:style => 'background: #fab444'. Here’s a list of some of the most commonFormHelperhelpers:
All these methods can be suffixed with_tagto create standard HTML tags (with no Active Record integration).
For a full list ofFormHelperandFormTagHelper methods, consult the Rails API, where you’ll find a complete reference along with usage examples:
Now, back to our form. Let’s see what happens when you submit it. (Make sure your server is still running.) Go ahead and click the Sign up! button. You’ll see the following message displayed on your screen:
-------------------------------------------- Unknown action No action responded to create --------------------------------------------
So, what happened here? Well, just as the message says, Rails wasn’t able to find an action calledcreateon theuserscontroller. Of course it couldn’t—we haven’t created one yet. If you look at the output from your server running on the console, you’ll see what happened:
See the section titledParameters? You might recognize this as a Ruby hash (we’ve formatted it prettily to make it easier to read). This hash contains all the form values we just submitted. Notice that there’s an entry for the controller (users) and the action we submitted to (create). Theuser portion of the hash looks like this:
If you’re thinking this looks a lot like the options hashes you were passing to theUserobjects when you were working with Active Record on the console, you’re right. Rails automatically turns form elements into a convenient hash that you can pass into your models to create and update their attributes. We’ll put this feature to use in our next action,create, which we’ll get to in a minute. First, let’s take a deeper look atparams.
Please check back for the continuation of this article.
DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.