Let’s use form_with (Ruby on Rails)

Raynaldo Sutisna
3 min readNov 9, 2020

--

Photo by Joshua Fuller on Unsplash

What is form_with?

form_with is a function that is created by Rails to generate an HTML form tag. It is like a handy shortcut for developers to create forms because forms in web applications are an important aspect for input data from users. Previously, other functions are already created by rails such as form_with and form_tag.

Why should we use form_with?

Firstly, form_with is invented to substituteform_for and form_tag because they are soft deprecated now.

The good news is form_with is powerful because the functionality covers form_for and form_tag . As we know that form_for is used when we use a model in the form, and form_tag is used without a model. Let’s see the example of the use of form_for and form_tag.

form_for

<%= form_for @course do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<% end %>
---generate to html---<form class="new_course" id="new_course" action="/courses" method="post" ...>
...
<label for="course_title">Title</label>
<input type="text" name="course[title]" id="course_title">
</form>

form_tag

<%= form_tag courses_path do |f| %>
<%= label_tag :title %>
<%= text_field_tag :title %>
<% end %>
---generate to html---<form action="/courses" method="post" ...>
...
<label for="title">Title</label>
<input type="text" name="title" id="title">
</form>

If we are using form_with , we can fulfill both needs, which are using a model or without any model.

using a model

<%= form_with model: @course do |f|%>
<%= f.label :title %>
<%= f.text_field :title %>
<% end %>
---generate to html---<form action="/courses" method="post" ...>
...
<label for="course_title">Title</label>
<input type="text" name="course[title]" id="course_title">
</form>

without any model

<%= form_with url: courses_path do |f|%>
<%= f.label :title %>
<%= f.text_field :title %>
<% end %>
---generate to html---<form action="/courses" method="post" ...>
...
<label for="title">Title</label>
<input type="text" name="title" id="title">
</form>

form_with also gives us an option about using block or not. If we aren’t using the block so we will use the form contents like form_tag

<%= form_with url: courses_path do %>
<%= label_tag :title %>
<%= text_field_tag :title %>
<% end %>

The difference between form_for and form_with is form_with doesn’t automatically create id and class attributes anymore, so if you want to add id and class attributes, we can use this syntax below.

<%= form_with model: @course, id: "course_id", class: "course_class" do |f|%>

validation error messages or flash aren’t working using form_with ? We need to use this option

<%= form_with model: @course, local: true do |f|%>

form_with Options

These are form_with options that are usually used

<%= form_with(
model: @course,
url: courses_path,
method: "post", # default : "post", "get", "patch", "update",
local: true, # if you have a problem with validation error message, you should put this.
#optional :
scope: "course", # prefix of parameter params["course"]["title"]
id: "course_id",
class: "course_class", #
html: {name : "course"}) # html attributes
do |f| %>

<%= f.label :title %>
<%= f.text_field :title %>
<% end %>

Documentation link: here

form_with elements

My notes for form elements

<%= form_with url: "/" do %>
<%= label_tag :title %>
<%= text_field_tag :title %>
<%= radio_button_tag :type, "music" %>
<%= check_box_tag :type %>
<%= text_area_tag(:message, "Hi, nice site", size: "24x6") %>
<%= password_field_tag(:password) %>
<%= hidden_field_tag(:parent_id, "5") %>
<%= search_field(:user, :name) %>
<%= telephone_field(:user, :phone) %>
<%= date_field(:user, :born_on) %>
<%= datetime_local_field(:user, :graduation_day) %>
<%= month_field(:user, :birthday_month) %>
<%= week_field(:user, :birthday_week) %>
<%= url_field(:user, :homepage) %>
<%= email_field(:user, :address) %>
<%= color_field(:user, :favorite_color) %>
<%= time_field(:task, :started_at) %>
<%= number_field(:product, :price, in: 1.0..20.0, step: 0.5) %>
<%= range_field(:product, :discount, in: 1..100) %>
<%= select_date Date.today, prefix: :start_date %>
<%= time_zone_select(:person, :time_zone) %>
<%= file_field_tag 'picture' %>
<% end %>

Documentation link: here

--

--

No responses yet