Railsのform_withのあれこれ【殴り描き】
form_withのあれこれ
Rails5.1以降に登場したform_with
の利用方法のメモ残す。
Rails5.1以前に利用されていたform_for
とform_tag
は非推奨になったので基本利用しないようにしましょう。
form_with
ではモデルに関連するもの、関連づかないフォームのどちらでも利用可能になります。
(以前はモデルに関連するものをform_for
、関連づかないフォームをform_tag
と使い分けていた)
モデルに関連するときの書き方
<%= form_with model: @user do |f| %> <%= f.text_field :name %> <%= f.submit %> <% end %>
form_with引数のインスタンス(@user)が何も情報を持っていない場合、createアクションへ、 情報を持っている場合、updateアクションへ自動的に振り分けてくれます。
例えば、newの場合は自動でcreateアクションに振り分けられる。 既に情報を持っているcreateの場合は自動でupdateアクションに振り分けられる。
モデルに関連づかない時の書き方
<%= form_with url: users_path do |f| %> <%= f.text_field :name %> <%= f.submit %> <% end %>
モデルに紐づかない場合はurlを明示的に記載する。
form_withの利用方法
form_with(model: nil, scope: nil, url: nil, format: nil, **options)
form_withで利用できるオプション
form_withではたくさんのオプションが利用できます。
以下のRails 5.1〜: ‘form_with’ APIドキュメント完全翻訳
に詳細説明が記載されています。
↓
https://techracho.bpsinc.jp/hachi8833/2017_05_01/39502
form_withの中でvalidationエラーを表示させるにはlocal_trueオプションが必須
form_withの中で以下のようにvalidationエラーを表示させようとしたのですが、何故か画面に表示されないケースがありました。
このコードはslimテンプレート利用してます、erbとslim混合して読みにくくてすいません。
...前略... = form_with model: @hoge do |f| / createに失敗するとエラー表示 - if @hoge.errors.any? .alert.alert-warning ul - @hoge.errors.full_messages.each do |message| li = message
最初はif @hoge.errors.any?
が作動してないのかな?と思ったのですが調べてみるとif分は正常に作動していました。
で、詳しく調べてみた結果オプションでlocal: trueを指定してないのが原因でした。 ですので、以下のような書き方が正解です。
= form_with model: @hoge, local: true do |f|
何故local_trueオプションが必須?
form_withでは何も指定しない場合デフォルトでremote: true
になるようです。
remote: true
ではXMLHTTPRequestオブジェクトリクエストを自動で送信するので、無効化する為にlocal: true
を指定してあげます。
<%= form_with url: posts_path do |form| %> <%= form.text_field :title %> <% end %>
html変換 ↓
<form action="/posts" method="post" data-remote="true"> <input type="text" name="title"> </form>
確かに自動でdata-remote="true
になっていますね。
参考サイト
https://api.rubyonrails.org/v6.0/classes/ActionView/Helpers/FormHelper.html#method-i-form_with