form_with vs. form_tag vs. form_for in Rails

Tram Ho

In the future, form_tag and form_for will not be used anymore and they will be replaced by form_with . If you want to know more about form_with , you can take a look at DHH’s proposal , check the pull request in which it was implemented, check the API documentation and try to create a project and use it.

Or, continue reading this article in which I explain the difference between form_tag , form_for and form_with with examples.

A syntax used for all

Previously when you wanted to create a form, but you didn’t have a basic model for it, you would use form_tag .

When you have a specific model, you will use form_for .

As you can see, we use form builder field helpers with form_for but we don’t do that with form_tag . Therefore, the syntax for each of these forms is different.

This situation will not happen with form_with , because we always use the form builder.

form_with has no model:

form_with with model:

When passing the model parameters, the scope and url are automatically taken from it. This is similar to form_for .

Automatic id and class are gone

form_tag and form_for automatically generate id for fields in the form. In addition, form_for also creates the id for the form.

Result:

With form_with , you must specify all your ids and classes manually:

Result:

Don’t forget to assign the id to the fields in the form if you want to make the label work.

Update: form_with will automatically generate ids from Rails 5.2, so you don’t need to manually assign them anymore.

Form id and class attributes are no longer included

Before:

With form_with :

Form fields do not have to correspond to model properties

Before:

With form_with :

Note that send_welcome_email will be restricted to the user in the controller parameters in the following example:

Therefore, I would probably still use check_box_tag instead of form.check_box if I need to.

All forms are remote by default

This change is the most interesting to me. All forms created by form_with will be sent by XHR (Ajax) request by default. No need to declare remote: true as you have to do with form_tag and form_for .

I like this feature, as it sends a message. Thanks to Turbolinks, (almost) all GET requests are XHR requests by default. And thanks to form_with , this can also become a reality for forms. You only need to do a little bit of work (create a JavaScript feedback form) and you won’t need to reload the page.

However, if you want to turn off remote forms then you can do so with local: true .

Please use form_with from now on

I won’t cover everything in this article, but it’s enough to get you started with form_with so you don’t have to use form_tag and form_for anymore (they will be deleted anyway). Also, read the documentation for form_with .

Source: Patrik Bóna

Share the news now

Source : Viblo