Rails – form関係ヘルパーの基本

概要

form系のヘルパーの基本的な機能・挙動について整理してみた。

  • form系の新旧4つのヘルパーの動作についてまとめた
  • モデルを介して複数のパラメーターを扱うform_forform_withのオーソドックスな使い方については、最後の「パラメーターを一括で扱う」にまとめた。

各formヘルパーの関係は

  • form_tagform_forform_withはHTMLのformタグを生成するRailsのヘルパー
  • Rails 5.1より前はform_tagform_for
  • Rails 5.1からform_withが導入され、form_tagform_forは非推奨に

form_tagform_forについては

  • form_tagはブロック内にtext_field_tagなどtag系のヘルパーを持つことを想定
  • データベースと紐づいたモデルを扱う場合はform_for、モデルを介さずにフォームのデータのみやりとりする場合はform_tagを使用

form_withについては

  • form_withform_tagの機能とform_forの機能を1つで使い分け

form_tag

動作

form_tagはフォームブロックの各要素の値を直接ハッシュで取り出すため、モデルは介在しない。

  • form_tagではアクションへのパスを指定し、アクションで各要素の値を参照する
  • 各要素の値は1次元のハッシュparamsに格納されている
  • 要素の値は要素のname属性をキーとして参照

コード間の流れ

app/views/top.html.erb

  • form_tagヘルパーの引数に、POSTを送るアクションへのパスを指定
    • パス指定にはroutes.rbで設定するエイリアスを使っている
  • 各要素ヘルパーの第1引数でid/name属性の値をシンボルで定義

config/routes.rb

  • form_tagからのPOSTを受け取るアクションへのルートを設定
  • URLにエイリアスを使っていて、それをアクションに紐づけている

app/controllers/pages_controller.rb

  • ルーティングの結果呼ばれたアクション内で、フォームの要素から送られた値を処理
  • 要素の値はparams[キーのシンボル]で取り出す

コンソール出力

  • 4行目でPOSTで送られるparams全体が表示されている
  • 6行目でparamsを表示させており、4行目と同じ内容
  • 7~8行目は個別の要素の値をキーを使って参照

form_for

動作

  • form_forでは第1引数にモデルのインスタンスを指定
    • モデルのインスタンスはコントローラーでインスタンス変数として準備
  • form_forでPOSTされた各要素の値はハッシュparams[モデル名のシンボル]に格納される
    • 要素の値を取り出すには以下のハッシュを参照
    • params[モデル名のシンボル][要素名のシンボル]
  • ここでは第2引数のURLでPOST先のアクションを指定している

コード間の流れ

より具体的な実装については、モデルによるフォームデータの取得を参照。

app/views/top.html.erb

  • form_forの第1引数にモデルのインスタンスを指定
    • インスタンスはコントローラーで生成
    • 第2に引数のurl:で指定したパスにPOST
  • form_forの構文は以下のとおり
    • form_for(モデル, オプション群) do |フォームビルダー|
  • 各要素の値はtext_fieldなどフォームビルダーのメソッドで要素名を指定して取得する

config/routes.rb

  • form_tagからのPOSTを受け取るアクションへのルートを設定
  • ここではurl:で指定したエイリアスからアクションに紐づけている

app/controllers/pages_controller.rb

  • ルーティングの結果呼ばれたアクション内で、フォームの要素から送られたデータを確認
  • 各要素の値はparams[モデル名のシンボル]にハッシュとしてまとめられている
  • 個別の要素の値はその中で要素名をキーとしてとりだせる
    • params[モデル名のシンボル][要素名のシンボル]

なお上の例ではform_forの引数に与えるモデルインスタンス(@user)を最初に生成しているが、コントローラーの中ではこれを使わず、ローカルな変数(user)を使っている。

コンソール出力

  • 4行目中、"record" => {"param_text" => "TEXT", ...}が各要素のデータ
  • 6行目に全要素のハッシュ、7~8行目に個別の要素の値が表示されている

form_with (データベースなし)

動作

  • 動作の内容はform_tagと同じ
  • そのためビューにおいてform_withの引数としてURLを指定(url: パス)

注意点

form_withはデフォルトでajaxによるフォーム送信となり、ページ全体がレンダリングされない。HTMLとして送信してレンダリングするには、パラメーターにlocal: trueを指定する。

<%= form_with(url: 'URL', local: true) do |f| %>

コード間の流れ

  • ビューでの書き方以外はform_tagと同じ流れ

app/views/top.html.erb

  • form_withの引数にURLを指定(url: パス)
  • モデルが介在しないform_tagと同じ動作をさせる書き方
  • 各要素はフォームビルダーのメソッドで書いている

config/routes.rb

app/controllers/pages_controller.rb

コンソール出力

form_with (データベースあり)

より具体的な実装については、モデルによるフォームデータの取得を参照。

動作

  • 動作の内容はform_forと同じ
  • そのためにビューにおいて引数にデータベースと紐づいたモデルを指定(model: モデルインスタンス)
  • ここでは第2引数のURLでPOST先のアクションを指定している

<%= form_with(model: 'model', url: 'URL', local: true) do |f| %>

コード間の流れ

app/views/top.html.erb

  • form_withの引数にモデルのインスタンスを指定している
    • model: モデルインスタンス名で指定
    • モデルのインスタンスはコントローラーで生成
  • モデルを介在したform_withと同じ動作をさせる書き方
  • 各要素はフォームビルダーのメソッドで書いている

config/routes.rb

app/controllers/pages_controller.rb

コンソール出力

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です