Rails のform_forを使ったフォームのController、View、Modelの連携がよく分からない、何となく動いているけど理解していないからカスタマイズなどできそうにないといった方向け、form_forメソッドを中心としたMVCが連携する処理フローを説明していきます。
動作確認
・Rails 4.1.0
処理フロー概要
1. Controllerのnewメソッド/editメソッド
でModelオブジェクトを生成しインスタンス変数(例:@userなど)に値を設定
2. Viewのform_forメソッド
でModelオブジェクトのカラムを使用したフォームを作成し、表示する。
3. ユーザがサブミットすると、params変数に入力したパラメータがハッシュの形で設定されてControllerに届く。
4. Controllerのcreateメソッド /updateメソッド
でparams変数でModelオブジェクトを作成/更新する。
という流れです。
新規登録フロー
前提
Userテーブルにはname
とemail
というカラムが存在していて、user.rbファイル
が作成されている。
# app/models/user.rb class User < ActiveRecord::Base end
1. Controllerのnewメソッド
でModelオブジェクトを生成しインスタンス変数に設定
# app/controllers/users_controller.rb ... def new # @user に空のModelオブジェクトを作成し、インタンス変数@userに設定 # @userはViewでも使える # Controllerでrenderやredirect_toなどで明示的にレンダリングするViewをしていない場合は、 # メソッド名のViewファイルがレンダリングされる(例:new => new.html.erb) @user = User.new end ...
2. Viewのform_forメソッド
でフォームを作成し、表示
# app/views/users/new.html.erb ... # form_forに@userを渡すことにより、Userテーブルのnameとemailカラムの # ラベルやテキストフィールドなどのinput要素を簡易に作成することができる <%= form_for @user do |f| %> <div class="field"> <%= f.label :name, "名前" %> <%= f.text_field :name %> </div> <div class="field"> <%= f.label :email, "メールアドレス" %> <%= f.text_field :email %> </div> <div class="actions"> <%= f.submit "登録する" %> </div> <% end %> ...
作成された画面のフォーム部分は...
作成されたHTMLは...
input属性
のname属性
に注目しといて下さい。これは、Model名とそのカラム名になっていることが分かると思います。
<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post"><div style="display:none"><input name="utf8" type="hidden" value="✓"><input name="authenticity_token" type="hidden" value="RIDGusRT/gJ2C+y+FKFV2P6rfN1mmNrQNWGX2sAtWrQ="></div> <div class="field"> <label for="user_name">名前</label> <input id="user_name" name="user[name]" type="text"> </div> <div class="field"> <label for="user_email">メールアドレス</label> <input id="user_email" name="user[email]" type="text"> </div> <div class="actions"> <input name="commit" type="submit" value="登録する"> </div> </form>
3. ユーザがサブミットすると、params変数に入力したパラメータがハッシュの形で設定されてControllerに届く
先ほどの、input要素
のname属性
をキーとしてハッシュ形式でparamsに設定されます。
params = { user: { # params[:user] で { name: "鈴木", email: "suzu..." } を取得可能 name: "鈴木", # params[:user][:name] で値を取得可能 email: "suzuki@example.com" # params[:user][:email] で値を取得可能 } }
4. Controllerのcreateメソッド
でparams変数でModelオブジェクトを作成
# app/controllers/users_controller.rb ... def create @user = User.new(user_params) if @user.save # @userはuser_path(@user) に自動変換される redirect_to @user, notice: "ユーザ登録しました。" else # ValidationエラーなどでDBに保存できない場合 new.html.erb を再表示 render 'new' end private # Rails4からStrongParamaterと呼ばれる機能が追加されました。 # セキュリティのため、permitメソッドで許可したパラメータ名しか取得できません。 def user_params params.require(:user).permit(:name, :email) end end
以上です。