Rails 5.1~ [ form_for / form_tag ] => form_with に統合!

5.1~ form_withという form_for, form_tag を統合するメソッドが追加になり、form_for, form_tag は非推奨になります。

今まではmodelあり、なしで form_for, form_tag を使い分けてたけど、form_withの場合はそれが必要ない。モデルある、なしに関わらず同じように記載できます。

以前(form_for / form_tag)

モデルあり

from_for @user do
    = text_field :email

モデルなし

form_tag root_path do |f|
    f.text_field_tag :email

5.1(form_with)

モデルあり

form_with model: @user do |f|
    f.text_field :email

モデルなし

form_with url: root_path do |f|
    f.text_field :email

注意

5.1ではform_withのinput 要素に id が付かない。

form_for @user do |f|
    f.text_field :email

↓

<form class="new_user" id="new_user" action="/users">
    <input type="text" name="user[email]" id="user_email" />
</form>           
form_with model: @user do |f|
    f.text_field :name

↓

<form action="/users">
    <input type="text" name="user[email]" />
</form>

5.2 〜はもとどおりつくよ!


非同期(Ajax)がデフォルト

今まではform_forで非同期(Ajax)するとき、form_for .. remote: true オプションをつける必要があった。

なんでデフォルトに?

DHHのコメント

Make remote: true the default. Full-page changes after submissions are rough. When using Turbolinks,
a normal redirect will generate a Turbolinks.visit() call, and otherwise there's SJR.
(We could consider having config.action_view.forms_remote_by_default that you could set to false, for people going old school).
  • リクエストを全部ajaxにして、フルページ再読み込みを避けたほうが早い
  • これまではturbolinksでリンクはajaxになり、今回はformもajaxに!
  • turbolinksを使ってるとき、submitはredirectはturbolinks.visit()が呼び出されて、通常と同じようになる。
  • ただし入力エラーになったとき、SJR(Server-generated JavaScript Responses)で対応する

SJR(Server-generated JavaScript Responses)とは?

サーバ側(view)にレスポンス後に処理したいjs(xxx.js.erb)を書いて、レスポンスと一緒にそのjsを送る. ただエラーのたびにそれを書いているのは大変。。
↓便利そうなgemがありました。

  • ajax_error_renderer

    render_ajax_errorという、ajaxでエラーメッセージを表示するメソッドを提供する小さなgemです。Controller にAjaxErrorRendererをincludeすると使えるようになります。

今まで通り(remoteじゃない)の通信にしたい!

  • 全体を変える
config.action_view.forms_remote_by_default
  • form_tag ごとに変える
form_with model: object, local: true do |f|

参考