form_with trong Rails 5.1
Bài đăng này đã không được cập nhật trong 7 năm
Sắp tới form_for
và form_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_tag
và form_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_tag
và form_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