Come form_with Me
Form_with
With the impending deprecation of form_tag and form_for, I thought it’d be a good idea to familiarize myself with the form helper of the future, form_with.
For those who are unfamiliar with form helpers, they are Rails methods that are used in Ruby embedded HTML files to generate forms. Until recently, Rails provided two form helpers, form_for and form_tag. Form_for was developed to create forms to define attributes of objects that belong to an underlying model. Conversely, form_tag was introduced to create forms that could be used when there was no underlying model present. Form_with was introduced recently, and is an all powerful form helper that can generate forms with and without a model.
Example
I figured the best way to get comfortable with form_with would be to make a new rails app and use it to create forms, rather than the form_for method that I had come to know and love.
The practice app that I made lists out a few NFL football teams, and their players. In my domain, a team has many players, and a player belongs to a team — a straightforward one-to-many relationship.
I decided to incorporate a form, using form_with, on a team’s show page to add a player to the team. It turns out that the syntax to create this form with form_with is almost identical to creating it with form_for. The only discernible difference is that you need to include a key-word argument before your model. This makes sense since form _with must also be able to take in url and scope parameters when an underlying model isn’t present.
The above code, results in the below form. This isn’t exactly earth shattering, but it does show that making the switch from form_for to form_with can be done without committing to a new syntactical structure.

In creating this example, I stumbled upon an unexpected issue. My data model requires that player objects hold a foreign key for the team that they belong to. I wanted to be able to assume the team ID without the user having to manually input some integer that they don’t even know. I hadn’t run into this with form_for yet, so this presented a good opportunity to dive into some form_with methods that I wasn’t familiar with.
The method that I ended up finding, was hidden_field. Hidden_field returns a hidden input tag tailored for accessing a specified attribute on an object assigned to the template.
hidden_field(object_name, method, options = {}) public
Disclaimer: It turns out that hidden_field is originally a form_for method that has been included in form_with.
The hidden_field method creates a new key in the params hash that points to some value that you can assign (optional). In my example, I created a key called team_id that pointed to the ID of the team whose show page I am currently on. This created the following params hash, allowing me to pass the team_id to the controller, and ultimately create the new player record.
<ActionController::Parameters {“authenticity_token”=>”90+8L/O1L5LHaEJDcl5b17n1XezbW75wY6QjXjKojIP7d4LIvXCYYD+uFJWa7wGvI7tFLOU6VOa3gjfRUj/G1Q==”, “player”=><ActionController::Parameters {“name”=>”JabrilPeppers”, “number”=>”21", “team_id”=>”1"} permitted: false>, “commit”=>”Add Player to the Giants”, “controller”=>”players”, “action”=>”create”} permitted: false>
Summary
If there are any key takeaways from this blog, they are that form_with can be used almost exactly the same as form_for, and hidden_field is a great tool for manipulating your params hash.
