0
0
RailsComparisonBeginner · 4 min read

Form_with vs form_for in Rails: Key Differences and When to Use Each

form_for is the older Rails helper for building forms tied to a model, while form_with is the modern, unified helper introduced in Rails 5.1 that supports both model and non-model forms with better defaults and flexibility. form_with encourages remote forms by default and uses a simpler syntax.
⚖️

Quick Comparison

Here is a quick side-by-side comparison of form_for and form_with in Rails.

Featureform_forform_with
Introduced in Rails versionRails 2.0Rails 5.1
Supports model formsYesYes
Supports non-model formsNo (requires manual setup)Yes
Remote (AJAX) forms defaultNo (remote: true needed)No (remote: true must be set explicitly)
Syntax styleBlock with model objectBlock with model or URL
HTML id and class defaultsBased on model nameMore customizable and minimal
⚖️

Key Differences

form_for was designed specifically for forms tied to Active Record models. It automatically generates form fields based on the model's attributes and sets HTML element IDs and names accordingly. However, it does not support non-model forms easily and requires extra options for remote AJAX behavior.

form_with was introduced to unify form helpers and simplify form building. It supports both model-backed and plain URL forms with the same syntax. By default, form_with submits forms via standard HTTP requests (not AJAX) unless remote: true is specified. It also generates simpler HTML IDs and classes, making customization easier.

Another difference is that form_with uses keyword arguments and a more flexible API, encouraging cleaner and more consistent code. While form_for is still supported for legacy reasons, form_with is the recommended helper for new Rails applications.

⚖️

Code Comparison

Here is how you create a form for a @post model using form_for:

erb
<%= form_for @post do |f| %>
  <%= f.label :title %>
  <%= f.text_field :title %>

  <%= f.label :body %>
  <%= f.text_area :body %>

  <%= f.submit "Save" %>
<% end %>
Output
<form> with fields for title and body, and a submit button labeled 'Save'.
↔️

form_with Equivalent

The equivalent form using form_with looks like this:

erb
<%= form_with model: @post do |f| %>
  <%= f.label :title %>
  <%= f.text_field :title %>

  <%= f.label :body %>
  <%= f.text_area :body %>

  <%= f.submit "Save" %>
<% end %>
Output
<form> with fields for title and body, and a submit button labeled 'Save', submitted via standard HTTP request by default.
🎯

When to Use Which

Choose form_with for all new Rails projects because it is the modern, flexible helper that supports both model and non-model forms and uses AJAX when remote: true is specified. It leads to cleaner code and better user experience with less setup.

Use form_for only if you are maintaining legacy Rails code that already uses it extensively or if you need very specific behavior that form_with does not cover yet.

Key Takeaways

form_with is the modern, recommended form helper in Rails 5.1+.
form_for is older and model-specific, while form_with supports both model and non-model forms.
form_with submits forms via standard HTTP requests by default; use remote: true for AJAX.
Use form_with for new projects and form_for only for legacy support.
form_with has a cleaner, more flexible syntax with keyword arguments.