7月枠も残りわずか】当社人気の転職保証コース
プログラミング学習から転職成功まで導く、当社人気のDMM WEBCAMP(旧WEBCAMP PRO)。
6月受入枠は満員となっております。7月枠に向け、お早めの申込みをオススメします。
プログラミング未経験でもエンジニア転職を絶対成功させたい
スキルを身に着けて人生を自ら切り開きたい

上記にあてはまる方は、ぜひご検討ください!

はじめに

form_forヘルパーを使うことで、フォームを簡単に設置できます。

そのため、多くのRailsアプリケーションで使われています。

しかし、form_forヘルパーがどんな動きでフォームを作っているのか、理解して使っているでしょうか?

もし、あいまいなまま使っているのであれば、ぜひ本記事を一読してください。

また、初めてform_forヘルパーを使ったViewファイルを見て、「よく分からない」という人は、チャンスです。

この記事を読んで、form_forヘルパーを理解してください。

ここでは、form_forヘルパーについて、簡単に詳しく解説します。

なお、form_forヘルパーは、Rails5.1から非推奨(将来的になくなる可能性がある)になりました。Rails5.1以降にform_forヘルパーの代わりとなるform_withヘルパーについては、「【Rails入門説明書】form_withについて解説」を参照してください。ただし、form_forヘルパーを理解してからの方が、断然、分かりやすいので、まずは本記事を読まれることをおすすめします。

form_forを読み解く

まずは、実際のプログラムコードを見ながら、form_forがどういった動きをしてフォームを作っているのか、説明していきましょう。

環境作成

scaffoldを使えば、簡単に具体例を作れますので、まずはテスト用の環境を作ります。コマンドプロンプトで以下のコマンドを順に実行してください。
※詳細は、「【Rails入門説明書】scaffoldについて解説」を確認してください。

rails new form_test
cd form_test
rails generate scaffold User name:string age:integer email:string password:string note:text
rake db:migrate
rails c
User.create(name:"Arioka", age:30, email:"dai@hese.jp", password:"0000", note:"member")
User.create(name:"Yamada", age:28, email:"ryo@hese.jp", password:"1111", note:"top")
exit
お使いのRailsバージョンが5.1以上の場合は、form_withメソッドが使われます。
そのため、Viewのフォームをしている_form.html.erbの1行目を修正しておいてください。
(app/views/users/_form.html.erb)
・変更前

<%= form_with(model: user, local: true) do |form| %>

・変更後

<%= form_for(user) do |form| %>

念のため、サーバーを起動し、ブラウザで「localhost:3000/users」にアクセスしてみましょう。

フォームの確認

まずは、scaffoldで作成したフォームapp/views/users/_form.html.erbを見てみましょう。

少し長いですが、プログラムコードと、生成されるHTMLの抜粋が以下です。
(app/views/users/_form.html.erb)

<%= form_for(user) do |form| %>              <!-- (1) -->
  <% if user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
      <% user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :name %>                  <!-- (2) -->
    <%= form.text_field :name %>             <!-- (3) -->
  </div>

  <div class="field">
    <%= form.label :age %>                   <!-- (2) -->
    <%= form.number_field :age %>            <!-- (4) -->
  </div>

  <div class="field">
    <%= form.label :email %>                 <!-- (2) -->
    <%= form.text_field :email %>            <!-- (5) -->
  </div>

  <div class="field">
    <%= form.label :password %>              <!-- (2) -->
    <%= form.text_field :password %>         <!-- (6) -->
  </div>

  <div class="field">
    <%= form.label :note %>                  <!-- (2) -->
    <%= form.text_area :note %>              <!-- (7) -->
  </div>

  <div class="actions">
    <%= form.submit %>                       <!-- (8) -->
  </div>
<% end %>

form_forヘルパーそのものは(1)の行で使われ、form_forヘルパーのブロック引数formが得られています。このブロック引数formは、form_forヘルパーに渡されているモデルオブジェクトの情報を保持するFormBuilderオブジェクトです。

そして、FormBuilderオブジェクトのメソッドを使っているのが、(2)から(8)の部分です。この点を踏まえて、生成されるHTMLを見てみます。
(※FormBuilderはHelperを継承していますので、Helperのメソッドも使えます)

(新規作成画面で生成されるHTMLの抜粋)

<form class="new_user" id="new_user" action="/users" method="post">     <!-- (1) -->

  <div class="field">
    <label for="user_name">Name</label>                                                        <!-- (2) -->
    <input type="text" name="user[name]" id="user_name" />                                     <!-- (3) -->
  </div>

  <div class="field">
    <label for="user_age">Age</label>                                                          <!-- (2) -->
    <input type="number" name="user[age]" id="user_age" />                                     <!-- (4) -->
  </div>

  <div class="field">
    <label for="user_email">Email</label>                                                      <!-- (2) -->
    <input type="text" name="user[email]" id="user_email" />                                   <!-- (5) -->
  </div>

  <div class="field">
    <label for="user_password">Password</label>                                                <!-- (2) -->
    <input type="text" name="user[password]" id="user_password" />                             <!-- (6) -->
  </div>

  <div class="field">
    <label for="user_note">Note</label>                                                        <!-- (2) -->
    <textarea name="user[note]" id="user_note"></textarea>                                     <!-- (7) -->
  </div>

  <div class="actions">
    <input type="submit" name="commit" value="Create User" data-disable-with="Create User" />  <!-- (8) -->
  </div>
</form>

プログラムコードの(1)から(8)が、HTMLの(1)から(8)の部分に該当しています。

(1)の部分を比較すると、form_forヘルパーによってフォームが生成されています。そして、(2)から(8)のFormBuilderオブジェクトのメソッドが、フォームの各部品(フォームコントロール)を生成しているわけです。

form_forが生成するフォーム

もう少し、form_forヘルパーがどうやってフォームを生成しているのか、プログラムコードと生成されるHTMLを並べて、確認してみましょう。
(app/views/users/_form.html.erb)

<%= form_for(user) do |form| %>              <!-- (1) -->
<form class="new_user" id="new_user" action="/users" method="post">     <!-- (1) -->

プログラムコードの「do |form|」については、ブロック指定ですのでここでは無視します。すると、「form_for(user)」がここでのform_forヘルパーのコードということになります。

たったこれだけのコードだけで、適切なフォームが生成されます。Railsの自動推測によって、form_forヘルパーに渡されたモデルオブジェクト(今回はuser)から、HTMLのactionとmethodの値を推測してくれているのです。

今回は新規作成であるため、userはnewされたばかりで、値が入っていません。そのため、新規作成用のフォームが生成されています。

なお、編集画面の場合のHTMLは以下です。

<form class="edit_user" id="edit_user_1" action="/users/1" method="post">              <!-- (1) -->

プログラムコードは同じですが、userオブジェクトが値を持っているかどうかで、classやid、actionの値が適切に変わっています。

FormBuilderオブジェクトのメソッドが生成するフォームコントロール

次に、FormBuilderオブジェクトのメソッドがどんな解釈をされて、フォームコントロールが作られているのかを見ていきましょう。

(app/views/users/_form.html.erb)

    <%= form.label :name %>                <!-- (2) -->
    <%= form.text_field :name %>           <!-- (3) -->

(HTML)

    <label for="user_name">Name</label>                                 <!-- (2) -->
    <input type="text" name="user[name]" id="user_name" />              <!-- (3) -->

(3)のテキストボックスについては、text_fieldメソッドが生成してくれます。

引数として渡しているシンボルから格納すべき値を推測しますが、このとき、メソッドを利用しているFormBuilderオブジェクトが保持しているモデルの情報に紐づけ、user[name]を格納先に指定してくれます。(idも同様)

ラベルについても同じく、labelメソッドの引数から関連付けるコントロールのidが推測されています。

なお、form_forヘルパーが生成したフォームで入力した値については、コントロールからparams[モデル名][カラム名]のハッシュ(ここでは、params[user][name])でアクセスすることができます。

コツコツ独学×スクールで実践。未経験からエンジニアに転職!【WebCamp卒業生インタビュー】

form_forの詳細情報

Railsの基本的な動き通り、form_forヘルパーもシンボル名などから推測して処理を追加してくれます。

とても便利ではあるのですが、それでは思ったような動きができないことがあります。そんな場合にカスタマイズできるオプション設定がありますので、form_forヘルパーの構文とともに紹介しましょう。

構文

form_for(モデルオブジェクト , オプション) do |f|
  フォームコントロールの設置
end

オプションには、以下があります。

オプション 説明 デフォルト
:url フォームの送信先 現在のURL
:namespace 名前空間の設定をしているコントローラへデータを渡したい場合の名前空間 名前空間なし
:method HTTPリクエスト POST
:authenticity_token クロスサイト・リクエストフォージェリ(CSRF)という脆弱性に対策するための認証トークンの無効化や変更 デフォルトトークン
:remote trueを指定すると、Unobtrusive JavaScript(控えめなJavaScript)で送信する情報を制御できる false(Ajaxでの送信)
:enforce_utf8 IE5以前のブラウザの文字化け対策用に埋め込むHiddenパラメータの出力設定
true:出力
false:出力しない
true
:html フォームコントロールにHTML属性をつける 属性なし
:as モデルの名称を一時的に設定する モデル名

テスト環境のform_forヘルパー(app/views/users/_form.html.erb)について、敢えてオプション設定を使って記載すると、以下のようになります。

<%= form_for user, 
             as: :user,
             url: users_path,
             html: { class: "new_user", id: "new_user" } do |form| %>

userがnewしたばかりの場合、Railsは裏でこのような設定を行って処理しているのです。

参考として、編集の場合は、以下のようになるでしょう。

<%= form_for user, 
             as: :user,
             url: user_path(user),
             method: :patch,
             html: { class: "edit_user", id: "edit_user_1" } do |form| %>

この形を憶えておくと、オプションによるカスタマイズがやりやすいかもしれません。

なお、オプション設定の中で、:urlオプションと:namespaceオプション、:htmlオプションの3つは比較的よく使いますので、少し詳しく説明しておきましょう。

フォームで入力された情報の送信先を変える

「:url」オプションを使えば、入力データの送信先を変更できます。

例えば、新規登録画面で入力したデータで更新する場合のプログラムコードを紹介しましょう。(新規登録したデータが、登録済みの人の場合に、更新するといった場合に必要になるかもしれません)

form_forヘルパーに、以下のようにオプションを追加してみましょう。
(app/views/users/_form.html.erb)

<!-- <%= @user = User.find(1) %> -->
<%= form_for (user, 
             url: user_path(@user),
             method: :patch,
             html: { class: "edit_user", id: "edit_user_1" }) do |form| %>  <!-- (1) -->

なお、上書きする既存のデータを指定するため、変数@userを追加しています。

「localhost:3000/users/new」にアクセスして[Create User]をクリックしても、データは3つのままで、追加しようとした情報が、1つ目のデータに上書きされます。

フォームにHTML属性をつける

フォームに自動で付与されるidやclassなどを変更したり、他のHTML属性をつけたりする場合に使うのが「:html」オプションです。

「:html」オプションに、ハッシュでHTML属性を渡すことで、フォームにHTML属性を設定することができます。

(app/views/users/_form.html.erb)

<%= form_for(user,
             html: { class: "test_form", id: "test_form" }) do |form| %>  <!-- (1) -- >

見た目は変わりませんが、HTMLは以下のようになっています。(抜粋です)

<form class="test_form" id="test_form" action="/users" method="post">     <!-- (1) -->

別の名前空間のコントローラへフォームで入力された情報を送信する

例えば、同じ商品テーブルからデータを表示するが、会員と非会員で画面を変えたい場合などは、それぞれ別のディレクトリを作って、コントローラもViewも別に管理した方が、メンテナンス性は高いでしょう。

そのような場合、ルーティングでディレクトリ名の名前空間を設定して対応します。そうすることで、Railsがディレクトリを推測して、正しいコントロール(アクション)へアクセスするURLを生成してくれるのです。

未経験から上京し、エンジニアとしてチームラボグループに転職!【WebCampPro卒業生インタビュー】

form_forが生成するフォームコントロール

form_forヘルパーのブロック引数として得られるFormBuilderオブジェクトのメソッドが、フォームコントロールを生成します。

このとき、メソッドによって生成されるフォームコントロールが違いますので、必要なメソッドを知らなければいけません。

ここでは、メソッドの種類と生成されるフォームコントロールについて、紹介しましょう。

メソッド 説明 オプション(入力対象カラムの後の引数)
check_box チェックボックス HTML属性を設定可能
color_field 色の入力欄 HTML属性を設定可能
date_field 日付の入力欄 デフォルト値とHTML属性を設定可能
datetime_field 日時の入力欄(グローバルタイム) HTML属性を設定可能
datetime_local_field 日時の入力欄(ローカルタイム) HTML属性を設定可能
email_field emailアドレスの入力欄 HTML属性を設定可能
fields_for form_forの中で別のモデルを指定したフォーム form_forと同じ
file_field 画像や文章などのファイルを選択するフォーム HTML属性を設定可能
hidden_field 隠しフィールドの生成 HTML属性を設定可能
label ラベルの生成 HTML属性を設定可能
month_field 月の入力欄 最小値(:min)、最大値(:max)、粒度(:max)、HTML属性を設定可能
粒度は、数字を増減させるためのボタンで増減される値
number_field 数値入力欄
数字以外は入力不可能
HTML属性を設定可能
password_field パスワード入力欄
入力された文字は自動的に*表示(マスク)される
HTML属性を設定可能
phone_field
telephone_field
電話番号入力欄 HTML属性を設定可能
radio_button ラジオボタンの生成 表示文言、チェックの有無(checked)、HTML属性を設定可能
range_field 範囲選択バー HTML属性を設定可能
search_field 検索ボックスフォーム HTML属性を設定可能
text_area 文字列入力欄
改行込みの文字列
HTML属性を設定可能
text_field 文字列入力欄 HTML属性を設定可能
time_field 時間入力欄 最小値(:min)、最大値(:max)、粒度(:max)、HTML属性を設定可能
粒度は、数字を増減させるためのボタンで増減される値
url_field URL入力欄 HTML属性を設定可能
week_field 週の入力欄 最小値(:min)、最大値(:max)、粒度(:max)、HTML属性を設定可能
粒度は、数字を増減させるためのボタンで増減される値
submit 送信ボタン 表示文言、HTML属性を設定可能
入力対象カラムは不要
表示文言を省略すると、モデルが保存済みかどうかで文言を変更する
(保存済み:「Update モデル名」 未保存:「Create モデル名」)

“未経験”でもたった1ヶ月で営業からエンジニアとして転職!『WebCamp』受講者インタビュー

まとめ

form_forヘルパーについて、お伝えしました。

form_forヘルパーを利用すれば、ユーザー登録や編集などのフォームが手軽に実装でき、Viewファイルのプログラムコードもすっきりと分かりやすいものになります。

Railsの特徴である名称による推測でプログラムコードが自動生成されますので、URLの管理などもほとんど行う必要がなく、メンテナンス性も高いと言えるでしょう。

しかし、その反面、自動生成されるために自由度が低く、オプションを駆使してカスタマイズできなければ、思ったような管理ができなくなりますので、しっかりと学習していきましょう。

ただし、冒頭にも書いたとおり、Rails5.1からはform_forは非推奨(将来的になくなる可能性がある)になりましたので、form_forヘルパーの代わりとなるform_withヘルパーについても、並行して学習を進めるようにしてください。

なお、form_withヘルパーについては、別の記事「【Rails入門説明書】form_withについて解説」で詳しく説明してますので、ぜひお読みください。

・form_forヘルパーで、フォームを簡単に設置できる
・form_forヘルパーで得られるFormBuilderオブジェクトのメソッドがフォームコントロールを生成する
・form_forヘルパーのオプションで、入力データの送信先を変更できる
・form_forヘルパーは、Rails5.1から非推奨(将来的になくなる可能性がある)になる。
・Rails5.1以降は、form_withヘルパーを使う

DMM WEWBCAMPについて

DMM WEBCAMPは3ヶ月間で未経験から即戦力エンジニアを育成する転職保障付きのプログラミングスクールです。1ヶ月でプログラミング・Webデザインを学ぶ通い放題の「ビジネス教養コース」も展開しています。

DMM WEBCAMPを運営する株式会社インフラトップ では、「学びと仕事を通して人生を最高の物語にする」という理念で会社を経営しています。

キャリアアップを目指す方は、この機会に私達と一緒にプログラミングを学んでみませんか?

7月枠も残りわずか】当社人気の転職保証コース
プログラミング学習から転職成功まで導く、当社人気のDMM WEBCAMP(旧WEBCAMP PRO)。
6月受入枠は満員となっております。7月枠に向け、お早めの申込みをオススメします。
プログラミング未経験でもエンジニア転職を絶対成功させたい
スキルを身に着けて人生を自ら切り開きたい

上記にあてはまる方は、ぜひご検討ください!


▼未経験から1ヶ月でWEBデザイン・プログラミングを学びたい方はこちら!

 

【インタビュー】1ヶ月でRubyをゼロから学び、Webエンジニアとして転職!

ブラジルから帰国し技術をつけようとRubyエンジニアを目指してWebCampでRubyを学び、見事Webエンジニアとして転職を果たした田中さんにお話を伺いました。

Rubyの学習がしたい。基礎をしっかりと理解したい

転職のサポートがほしい

と考えている方はぜひお読み下さい。

【WebCamp卒業生インタビュー】1ヶ月でRubyをゼロから学び、Webエンジニアとして転職!

おすすめの記事