form_with trong Rails 5.1

Sắp tới form_forform_tag sẽ được thay thế bởi form_with. Bài viết này tôi sẽ giải thích sự khác nhau giữa chúng thông qua các ví dụ

1. Một syntax cho tất cả

Trước đây khi chúng ta muốn tạo ra 1 form mà không muốn sử dụng 1 model nào cho nó thường chúng ta sử dụng form_tag.

<%= form_tag users_path do %>
  <%= text_field_tag :email %>
  <%= submit_tag %>
<% end %>

Khi sử dụng với 1 model chúng ta sử dụng form_for.

<%= form_for @user do |form| %>
  <%= form.text_field :email %>
  <%= form.submit %>
<% end %>

Như bạn thấy. syntax sử dụng 2 form ở trên là khác nhau. Nhưng với form_with thì sao ?

form_with không dùng model :

<%= form_with url: users_path do |form| %>
  <%= form.text_field :email %>
  <%= form.submit %>
<% end %>

form_with với model :

<%= form_with model: @user do |form| %>
  <%= form.text_field :email %>
  <%= form.submit %>
<% end %>

2. Không tự động tạo id và class

form_tagform_for tự động tạo ra id và class cho form field

<%= form_for User.new do |form| %>
  <%= form.text_field :email %>
<% end %>

sẽ tạo ra :

<form class="new_user" id="new_user" action="/users" ...>
  ...
  <input type="text" name="user[email]" id="user_email" />
</form>

Nhưng với form_with thì bạn phải tự định nghĩa giá trị bằng tay. Ví dụ :

<%= form_with model: @user do |form| %>
  <%= form.text_field :name %>
  <%= form.text_field :email, id: :email, class: :email %>
<% end %>

tạo ra :

<form action="/users" ...>
  ...
  <input type="text" name="user[name]" />
  <input id="email" class="email" type="text" name="user[email]" />
 </form>

Và đừng quên định nghĩa giá trị id cho form field nếu bạn muốn thẻ label hoạt dộng :

<%= form_with model: @user do |form| %>
  <%= form.label :name %>
  <%= form.text_field :name, id: :user_name %>
<% end %>

3. Không còn phải bọc các thuộc tính id và class nữa

Trước đây chúng ta vẫn thường viết :

<%= form_for @user, html: { id: :custom_id, class: :custom_class } do |form| %>
<% end %>

Còn giờ đây chỉ đơn giản :

<%= form_with model: @user, id: :custom_id, class: :custom_class do |form| %>
<% end %>

4. Các form field sẽ không cần phải bắt buộc là một thuộc tính của model nữa

Trước đây :

<%= form_for @user do |form| %>
  <%= form.text_field :email %>
  <%= check_box_tag :send_welcome_email %>
<% end %>

Với form_with :

<%= form_with model: @user, local: true do |form| %>
  <%= form.text_field :email %>
  <%= form.check_box :send_welcome_email %>
  <%= form.submit %>
<% end %>

Ở đây send_welcome_email là một scope tới user trong controller và param của nó sẽ có giá trị

params[:user][:send_welcome_email]

Tuy nhiên ở đây với form_with bạn vẫn có thể sử dụng cả 2 cách check_box_tag hoặc form.check_box.

5. Mặc định remote true

Mọi form được tạo bởi form_with sẽ được submit bởi Ajax. Bạn sẽ không cần phải khi báo remote: true giống như trước đây sử dụng form_tag hay form_tag nữa.

Nêú bạn muốn loại bỏ remote: true thì hãy sử dụng local: true

<%= form_with model: @user, local: true %>
<% end %>

6. Tổng kết

Trên đây chỉ là một vài điểm đặc sắc của form_with so với form_tagform_for trước đây. Nhưng nó cho ta thấy những điểm lợi ích và chuyển dần sang sử dụng form_with thay cho những phương thức cũ. Ngoài ra bạn có thể tìm hiểu thêm về form_with tại đây


All Rights Reserved