Railsのform_with
メソッドへの理解が曖昧だったので簡単にまとめました。
form_with の特徴
- Rails5.1以降は
form_tag
とform_for
が非推奨になり、替わりにform_with
が推奨になる form_for
的な使い方、form_tag
的な使い方の2つの使い方ができる- オプションの
()
は省略可能 - デフォルトのHTTPメソッドはPOST(他のHTTPメソッドも指定する可能)
remote: true
がデフォルト(Ajaxでの非同期通信)
form_withまとめ | Rails Ambassador ~Railsの伝道師~
2つの使い方
from_with
はform_tag
的な使い方、form_for
的な使い方の2つの使い方ができる
form_tag
的な使い方: 関連モデル無しform_for
的な使い方: 関連モデル有り
関連モデル無し(form_tag的)
指定したURLに対してパラメータを送信するフォームを作成する(DBにデータを保存しない)。
- HTTPメソッドは
POST
(デフォルト) - 送信したいURLは
url:
で指定する - 送信されたパラメータは
params[:email]
のような形で取得できる
# form_tagを使った書き方 <%= form_tag users_path do %> <%= text_field_tag :email %> <%= submit_tag %> <% end %>
# form_withで書き換え <%= form_with(url: users_path) do |f| %> <%= f.text_field :email %> <%= f.submit %> <% end %>
関連モデル有り(form_for的)
指定したモデルオブジェクトを元にフォームを作成する(DBに関連した処理を行う)。
# form_forを使った書き方 <%= form_for @user do |form| %> <%= form.text_field :email %> <%= form.submit %> <% end %>
# form_withで書き換え <%= form_with(model: @user) do |f| %> <%= f.text_field :email %> <%= f.submit %> <% end %>
指定したモデルオブジェクトのレコードの状態によって対応するコントローラーのアクション(create、update)を自動で切り替えてくれます。
Action View フォームヘルパー - Railsガイド
下記のルーティングが設定されている場合は次のような動作になります。
$ rails routes POST /users(.:format) users#create PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroy user GET /users/:id(.:format) users#show users GET /users(.:format) users#index new_user GET /users/new(.:format) users#new
パターン1: 指定したモデルオブジェクトが空の場合
下記のような新たに作成されたモデルオブジェクトを元にフォームを作成した場合はcreateアクション用のフォームが生成されます。
# app/controllers/users_controller.rb def new @user = User.new end
# app/views/users/new.html.erb <%= form_with(model: @user) do |f| %> <%= f.text_field :email %> <%= f.submit %> <% end %>
# 生成されるHTML <form action="/users" method="post"> ... </form>
- 送信されるURL:
/users
- HTTPメソッド: POST
- 実行されるアクション: users#create
パターン2: 指定したモデルオブジェクトが存在している場合
下記のように既存のモデルオブジェクトを元にフォームを作成した場合はupdateアクション用のフォームが生成されます。
# app/controllers/users_controller.rb def edit @user = User.find(params[:id]) end
# app/views/users/edit.html.erb <%= form_with(model: @user) do |f| %> <%= f.text_field :email %> <%= f.submit %> <% end %>
# 生成されるHTML <form action="/users/update対象のid" method="post"> <input type="hidden" name="_method" value="patch"> ... </form>
- 送信されるURL:
/users/update対象のid
- HTTPメソッド: PATCH
- 実行されるアクション: users#update
type=hidden
で隠しinput要素が追加で生成され、value="patch"
でデフォルトのHTTPメソッドのPOSTががPATCHに変更される
Action View フォームヘルパー - Railsガイド
まとめ
曖昧だったform_with
の使い方が理解できたのでスッキリした。
フォーム周りは複雑なのでガンガン触って覚えていきたい。
参照
form_withまとめ | Rails Ambassador ~Railsの伝道師~