Action View Form Helpers

Posted by Anthony Chao on 2019-10-01

Action View Form Helpers

今天要來看的是這篇

目前 Rails 比較推廣使用 form_with 來製作表單
以前的做法是:如果表格的對象有Model,則用form_for,Rails會利用Model的屬性來新增或更新Model所產生的資料;若沒有Model實體時,form_tag 則使用傳入連結的action進行表單傳送
現在 form_with 則是整合了這兩種做法,也對效能做了優化

因此在我看來差比較多的部分是,form_with 可以使用 url 後面帶一個真正的網址但 form_for 不行,除此之外 form_with 預設是用非同步的方式送出表單,如果要關掉這個設定要另外加個 local:true ,但是 form_for 則預設是同步的方式送出

話雖如此,但要注意一下使用的 gem 有沒有支援,像是 simple form 就不支援 form_with 這個用法


Tag_helpers

表單少不了的當然還有幫忙建出表單的這些欄位,tag_helpers 是一個最基本的用法,要注意的是,在這些 helpers 後面接的第一個參數一定是 name 這個屬性的值

1
<%= text_area_tag(:message) %>

在上面這個例子中, 可以在 html 原始碼看到這個屬性: name="message"


Model Objects

Model objects 可以視為是強化版的 tag_helpers,在使用的時候, rails 為了刻意區分他們, Model obejects 後面並沒有帶 tag
我們在使用 tag_helper 第一個參數一定要寫得很清楚,初始值也要自己設定,Model object 是 rails 做出比較方便使用的工具

在這些 helpers 後面第一個參數放的是實體的名字(這個例子中是 @person),第二個則是這個實體的方法(通常是屬性)

1
2
3
4
<!-- html.erb -->
<%= text_field(:person, :name) %>
<!--html-->
<input id="person_name" name="person[name]" type="text" value="Henry

上面這個例子中,是這個實體的名字本身帶有 “henry” 才會這樣顯示~


Model Objects 搭配表單

我們需要了解搭配表單使用的時候, model objects 實際上會變成怎樣:

1
2
3
<%= form_with model: @person do |person_form| %>
<%= person_form.text_field :name %>
<% end %>

檢視原始碼會看到:

1
2
3
4
<form action="/people" accept-charset="UTF-8" data-remote="true" method="post">
<input type="hidden" name="authenticity_token" value="bL13x72pldyDD8bgtkjKQakJCpd4A8JdXGbfksxBDHdf1uC0kCMqe2tvVdUYfidJt0fj3ihC4NxiVHv8GVYxJA==" />
<input type="text" name="person[name]" id="person_name" />
</form>

看到 name="person[name]" ,這代表表單內的 model objects 會自動幫你加上這個表單連結到的實體變數名字

當你的 model 前面有帶 namespace 的話,需要像下面這樣寫表單:

1
form_with model: [:admin, :management, @article]

另外,如果你這個表單不是要用 post 方法送的話,就要自己改寫:

1
form_with(url: search_path, method: "patch")

在原始碼中,你會看到這前兩行:

1
2
<form accept-charset="UTF-8" action="/search" data-remote="true" method="post">
<input name="_method" type="hidden" value="patch" />

會發現原始碼中竟然寫的還是 post,但是下面有一行 Rails 自己做出來的魔法:有一個隱藏的 input, name是 “_method” ,透過這行,Rails 會自己判別要改用 patch 的方法傳送資料

以上是今天的內容~ 希望對大家有幫助!

參考資料:

Rails Guide

Rails在建立表單的時候,form_for 跟 form_with 有什麼不同?

Rails 初心者的學習筆記:form_for和form_with的比較





prevent_hack