form_with是…?
在Rails 5.1之前,有兩種表格,一個是 form_tag
,一個是 form_for
,兩者有些微差異。在以前,如果表格的對象有Model,則用form_for
,Rails會利用Model的屬性來新增或更新Model所產生的資料;若沒有Model實體時,form_tag
則使用傳入連結的action進行表單傳送。Rails 5.1出來後,將兩者結合,成為 form_with
。
不管是用url或是model,都可以用form_with製作表格
使用form_with製作表格的對象”沒有Model”時:
<%= form_with url: new_owners_path do |form| %>
<%= form.text_field :email %>
<%= form.submit %>
<% end %>
看看HTML:
<form action="/owners/new" data-remote="true" method="post">
<input name="utf8" type="hidden" value="✓" />
<input type="hidden" name="authenticity_token" value="...." /> <input type="text" name="name" id="name" />
<input type="submit" name="commit" value="Save " data-disable-with="Save " />
</form>
使用form_with製作表格的對象”有Model”時:
<%= form_with model: Owner.new do |form| %>
<%= form.text_field :email %>
<%= form.submit %>
<% end %>
看看HTML:
<form action="/owners" accept-charset="UTF-8" data-remote="true" method="post">
<input name="utf8" type="hidden" value="✓" />
<input type="hidden" name="authenticity_token" value="..." /> <input type="text" name="owner[name]" id="owner_name" />
<input type="submit" name="commit" value="Create Owner" data-disable-with="Create Owner" />
</form>
由此可見,兩者幾乎是一樣的,差別只在於我們是告訴form_with
我們要用Model或是用url建立表格。
使用form_with時,建立時就已經預設了remote: true
我們先用form_with
建立一個表格:
<%= form_with model: Message.new do |form| %>
<%= form.text_field :subject %>
<% end %>
打開HTML來看:
<form action="/messages" method="post" data-remote="true">
<input type="text" name="subject">
</form>
可以看到data-remote="true"
。有了這個屬性之後,表單會透過 Ajax 提交,而不是瀏覽器平常的提交機制。如果不要設定Ajax提交,則要另訂 local: true
。
使用form_with時,Model不一定需要設定相對應的屬性
使用form_for
時:
<%= form_for @owner do |form| %>
<%= form.text_field :email %>
<%= check_box_tag :send_welcome_email %> ← 這一行
<%= form.submit %>
<% end %>
使用form_with
時:
<%= form_with model: @owner do |form| %>
<%= form.text_field :email %>
<%= form.check_box :send_welcome_email %> ← 這一行
<%= form.submit %>
<% end %>
form_with
新增的HTML:
<input name="owner[send_welcome_email]" type="hidden" value="0" /><input type="checkbox" value="1" name="owner[send_welcome_email]" id="owner_send_welcome_email" />
雖然Owner的Model中沒有這個屬性,你還是可以用FormBuilder寫出統一性的指令,而且這個資訊依然可以用owner[send_welcome_email]收集。
使用form_with時,HTML設定不用再需要使用{ }包起來
使用form_for
或是form_tag
時,若要設定如id、class,要如此寫:
<%= form_for @post, html: { id: “custom-id”, class: “custom-class” } do |form| %>
使用form_with
可以不用再用花括弧:
<%= form_with model: @post, id: “custom-id”, class: “custom-class” do |form| %>
最後再記錄一下使用form_with的寫法:
- 指定url時:
<%= form_with url: posts_path do |form| %>
<%= form.text_field :title %>
<% end %>
<%# ↓生成されるタグ %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="title">
</form>
2. 用scope帶入Prefix時:
<%= form_with scope: :post, url: posts_path do |form| %>
<%= form.text_field :title %>
<% end %>
<%# ↓生成されるタグ %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="post[title]">
</form>
3. 指定Model時:
<%= form_with model: Post.new do |form| %>
<%= form.text_field :title %>
<% end %>or<%= form_with model: @post do |form| %>
<%= form.text_field :title %>
<% end %><%# ↓生成されるタグ %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="post[title]">
</form>
以上範例引用Ruby on Rails 5.1 リリースノート
參考資料:
【Rails 5】(新) form_with と (旧) form_tag, form_for の違い