今まではモデルに関連するものは「form_for」、モデルに関連づかないフォームは「form_tag」と使い分けていましたがこれからはform_withで一本化されます。
form_forもform_tagも生成されるformタグは一緒なのでなかなか理解のむずかしいところでもありましたがこれで直感的にformを作成することができるのではないかと思います。
また、デフォルトでremote: :trueの設定になるのが大きな変更点です。
※formのデフォルトのHTTPメソッド(verb)はPOSTです。
<%= form_with url: users_path do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
関連モデル有
<%= form_with model: @user do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
引数に括弧がないとダメって方はもちろんできます。
関連モデル無<%= form_with(url: users_path) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
関連モデル有
<%= form_with(model: @user) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
<%= form_with scope: :session, url: sessions_path do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
<form action="/sessions" method="post" data-remote="true"> <input type="text" name="session[name]"> </form>
<%= form_with model: @user, id: :任意のID, class: :任意のclass do |form| %>
<%# フォームの部品 %>
<% end %>
引数括弧有
<%= form_with(model: @user, id: :任意のID, class: :任意のclass) do |form| %>
<%# フォームの部品 %>
<% end %>
今まではhtml: {id: "HOGE" のようにHTML属性を指定していたのが無くなるのは嬉しいですね!
form_with で生成されたフォームは、デフォルトで非同期通信XHR(Ajax)リクエストで送信されるようになります。
以前のform_tag と form_for のように、remote: trueの指定をする必要がありません。
viewもerbをレンダリングするのではなくJSで一部書き換えるようにすると非常に読み込みが早いページを簡単に作れますね。
もし以前のようなリモート無効のフォームにしたい場合は local: true を指定してください。(remoteではなくlocalになりますので注意!)
<%= form_with model: @user, local: true do |f| %>
<%# フォームの部品 %>
<% end %>
以前は「remote: true」で非同期にしていたのが「local: true」で解除されるっていうのは最初ちょっと勘違いするかもしれない部分かもしれません、
以下のようにモデル属性には無いhogeを指定することができます。
Userモデルにはhoge属性(カラム)が無い<%= form_with model: @user, url: users_path do |f| %>
<%= f.text_field :name %>
<%= f.text_field :hoge%>
<%= f.submit %>
<% end %>
以前はモデル属性に無い(テーブルにカラムが無い)入力フォーム(例えばhoge)を作成すると以下のようなエラーとなっていました。
undefined method `hoge' for User
この場合hoge属性(Attribute)を設定する必要がありましたが、form_withでは必要ありません。記述が短くなった分、エラーが出なくなったのでスペルミスなどの間違いに気づきにくくなるかもしれませんね。