hiyoko-programingの日記

プログラミングを勉強したてのひよっ子。   エンジニア目指して勉強中。

form_forとform_with

form_forとform_withの間には細かな違いはあるものの、使用感が大きく異なることはない。

  • 自動でパスを選択してくれて、HTTPメソッドを指定する必要が無いこと
  • コントローラーから渡された、ActiveRecordを継承するモデルのインスタンスが利用できること
  • inputタグは用いないこと

これらの特徴は共通。

Pictweetの投稿フォームをform_forとform_withで書いた時の違いを比較する。

【例】form_forで書いたPictweetのフォーム
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<div class="contents row">
  <div class="container">
    <%= form_for @tweet do |form| %>
      <h3>
        投稿する
      </h3>
      <%= form.text_field :name, placeholder: "Nickname" %>
      <%= form.text_field :image, placeholder: "Image Url" %>
      <%= form.text_area :text, placeholder: "text", rows: "10" %>
      <%= form.submit "SEND" %>
    <% end %>
  </div>
</div>
【例】form_withで書いたPictweetのフォーム
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<div class="contents row">
  <div class="container">
    <%= form_with(model: @tweet, local: true) do |form| %>
      <h3>
        投稿する
      </h3>
      <%= form.text_field :name, placeholder: "Nickname" %>
      <%= form.text_field :image, placeholder: "Image Url" %>
      <%= form.text_area :text, placeholder: "text", rows: "10" %>
      <%= form.submit "SEND" %>
    <% end %>
  </div>
</div>
上記は双方とも、コントローラーで@tweetを定義していると仮定

ご覧の通り、大きく違いはない。

正確には、form_withは、form_forとform_tagの機能を組み合わせたものである。しかし、「form_forと同じように使える」と把握するだけでも良い。より詳細に知りたい場合は、以下のような資料を確認すると良い。

Railsガイド Ruby on Rails 5.1 リリースノート

https://railsguides.jp/5_1_release_notes.html#form-for%E3%81%A8form-tag%E3%81%AEform-with%E3%81%B8%E3%81%AE%E7%B5%B1%E5%90%88
Rails公式GitHubのプルリクエスト

https://github.com/rails/rails/pull/26976

local: true オプション

form_withでは、デフォルトの状態ではremote: trueというajaxでの通信が行われる設定になっている。現状ではこのajax通信は必要のない機能である。それをキャンセルするためにlocal: trueというオプションを付与する必要がある。local: trueオプションを付与すれば、これまでのRailsのフォームと同様に使用することが出来る。