Sean Delaney
4 min readNov 13, 2020

--

Form_for and Form_tag

When learning Rails, one of the first things we’re introduced to is forms, which allow users to submit data into form fields. Forms in Rails allow us to meet the first requirement of CRUD, create, by allowing users to create new database records, build a contact form, and search in a search field. Rails gives us the flexibility to use built-in form helper methods and plain HTML form elements, but in this blog I will be focusing on the main differences between form_for and form_tag. While form_tag is often glossed over by beginner developers for the greatly preferred and powerful, form_for, it is also a flexible tool that forces one to be conscious of the routes and requests one’s form is making.

Form_Tag

Say we wanted to create a form that added a user to our database with their name, email, and password; we simply begin by writing form_tag on the view page where we would like to create our user form. With the form_tag helper we have to tell it exactly what we’re doing with the form, it makes no assumptions about the route it should take, or the type of request we’re sending. In the example below, we’re sending a post request to the users_path. Because we want to create new users with a name, email, and password, we need to make use of tag helpers which correspond to the type of data our users will be inputting.

These form helpers aren’t magic, they’re simply Ruby methods which take in arguments, such as the user’s email address. For every tag helper in our form we have to specify that each attribute the user is inputting values for is associated with a user table, which makes the form_tag an inefficient helper method for creating forms which require many user inputs. Where the form_tag really shines is when it’s used as a search form because it doesn’t need to be directly connected with models.

Form_For

The form_for helper is a powerful tool for creating forms that are directly connected to our models. From our create a user example above, the form_for helper will allow us to create a new user that connects directly to the user database table. In the example below, the form_for helper takes in an instance of the user model as an argument, which allows form_for to make a number of assumptions for us. Instead of having to specify the route and type of request we’re making, form_for automatically follows the standard route because it knows RESTful conventions.

Unlike our form_tag form, the form_for helper gives us an iterator variable, |f|, that we can use on the new form object that will allow us to dynamically assign form field elements to each of the @user's data attributes. Instead of having to write out user[first_name], user[last_name], etc., we simply call on the data attributes for the instance we are creating.

Form_for is a great choice when we want to make a form partial that we can use on our new and edit pages, because we can simply change our submit button text while using the same form for both pages. Form_for is often the best choice for edit pages because it’s able to auto-fill the values for each field; we get this ActionView functionality because form_for gives us access to the FormBuilder module in Rails.

When I was first learning about forms in Rails it seemed like form_for was the obvious choice every time I needed to make a form, but although its “magic” is powerful and easy to use, form_tag is a flexible option in a variety of situations. In fact, using form_tag forces a new developer to be conscious of the requests their form will make and the routes it will follow, before using a powerful tool like form_for, which renders a lot of that work invisible on the surface.

--

--