form_forで出来ること
from_forを使うことで入力フォームに必要なHTMLを作成することができます。
お問い合わせ画面とかで名前や内容等を入力する部分のとこです。
下準備
まずは、form_forを使っていく下準備としてscaffoldでモデルやコントローラー、ルーティング等を簡単に作っていきます。
rails new training
cd training
rails g scaffold user name:string email:string
rails db:migrate
今回は練習のためformヘルパーは使わずにフォームを作成していきたいと思うので
以下のように該当するviewを修正してください。
<h1>New User</h1>
<%= form_for @user do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.submit '送信' %>
<% end %>
使い方と処理の流れ
今回は、ユーザー新規登録時に新しくデータを入力する際のケースについて書いていきます。
1.コントローラー内で空のオブジェクトを生成する。
さきほどコマンドでscaffordを実行したので自動的にusersコントローラー内にCRUDに関するメソッドが書かれていると思います。
実際にusersコントローラーを確認してみましょう。
# GET /users/new
def new
@user = User.new
end
一部抜粋ですが、usersコントローラーのnewメソッド内では空のUserモデルを作ってそれを@userインスタンス変数に代入しています。
2.viewにフォームを書く
次に、該当するviewにフォームを書いていきます。@userインスタンス変数をform_forに引数として渡します。
<h1>New User</h1>
<%= form_for @user do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.submit '送信' %>
<% end %>
-
form_forメソッドの書き方
fomr_for モデルクラスのオブジェクト do |f|
が基本になります。
以下のように、引数に()を付けることも出来ます
fomr_for (@user) do |f|
-
入力フォームの構造
f.htmlタグ名 :カラム名
書き終わったら画面でHTMLの中身を確認してみましょう。
以下のように表示されているはずです。
<form class="new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="0+Ifi1D0zy2bXJ6LIIjlxgXuLXJFiziznUA+tbFXk2eq2FPzSVDooaqgmNCsHuwljm25T9dcXUGVuAk+RZ/b/g==">
<label for="user_name">Name</label>
<input type="text" name="user[name]" id="user_name">
<label for="user_email">Email</label>
<input type="email" name="user[email]" id="user_email">
<input type="submit" name="commit" value="送信" data-disable-with="送信">
</form>
- inputタグ内の説明
inputタグ内のaction属性とmethod属性のそれぞれの属性値の意味について確認します。
actionの属性値 → 送信先のパス
methodの属性値 → httpメソッド(get,postなど…)
今回の例で当てはめると以下のようになります
action="/users" → 送信先のパスが /users
method="post" → 使用されるhttpメソッドが post
※HTMLのinputタグ内のname属性値はモデル名[カラム名]
の構造になっています。
- createアクションかupdateアクションを実行する際の基準
form_forに渡されたオブジェクトが何も情報が入っていない場合(オブジェクトがnilの場合)はcreateアクションを送るようにform_for側で自動的に判断してくれます。
反対に、オブジェクトに何か値が入っている場合はupdateアクションを自動的に振り分けてくれます。
また、引数にgetやpostなどのhttpメソッドは書いても書かなくてもどちらでも構いません。
- form_forで使用できる主なタグ
- f.label 対応するラベルを作成
- f.text_field 一行のテキスト投稿フォーム
- f.text_area 複数行のテキスト投稿フォーム
- f.email_field メールアドレス用のフォーム
- f.check_box チェックボックス
- f.file_field 画像アップロード時などのファイル選択ボックス
- f.submit 送信ボタン
他にも色々あるので必要なものは適宜調べてみてください!
3.送信ボタンを押した後は、入力された値をparams変数にハッシュ形式で渡す
2.viewにフォームを書く
で説明したHTML内のinputタグのname属性をキーとしてparams変数にハッシュ形式で値を渡します。
今回はnameフォームに”hoge",emailフォームに"hogehoge@mail.com"と入力してみました。
params = {
user: {
name: "hoge"
,email: "hogehoge@mail.com"
}
}
4.ストロングパラメータでparamsの値を引き出し、createアクション内のnewメソッドに引数として渡す。
ストロングパラメータに関する説明は長くなりそうなのでまた別の記事で書こうと思うので割愛しますが、こちらではpermitで書かれているパラメーターのみが登録の対象となります。
したがって、age:20とかを登録することは出来ません。
# POST /users
# POST /users.json
def create
# user_params(ストロングパラメータ)を呼び出す
@user = User.new(user_params)
respond_to do |format|
if @user.save
# redirect_to @user は user_path(@user)と同義
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: @user }
else
format.html { render :new }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
private
# Never trust parameters from the scary internet, only allow the white list through.
#params変数内でpermit(許可)された値のみを呼び出し元に渡す。
def user_params
params.require(:user).permit(:name, :email)
end
最後に
誤っている箇所や追記した方が良い点等ございましたら
編集リクエストやコメントの方でご指摘していただけると幸いです。
参考
【Rails】form_forの使い方を徹底解説!
Railsのform_forを使ったフォームのController,View,Modelの連携した処理フロー