前提
例題として以下のようなモデルを使う。
- モデル名はuser
- モデルのフィールドは
name
とpassword
の2つで、いずれもstring
手順
モデルインスタンスとフォームの準備
フォームを呼び出すコントローラーで、モデルインスタンスを準備する。
app/controllers/pages_controller
1 2 3 4 5 |
class PagesController < ApplicationController def params_check @user = User.new end end |
フォーム側で、そのインスタンスを引数にとる。
app/views/pages/params_check.html.erb
1 2 3 4 5 |
<%= form_with(model: @user, url: params_check_process_path, local: true) do |form| %> <%= form.text_field(:name, placeholder: "名前を入力") %> <%= form.password_field(:password, placeholder: "パスワードを入力") %> <%= form.submit("登録") %> <% end %> |
フォームデータの取得
パラメーター取得の考え方
モデルを介してフォームデータを取得する考え方は以下の通り。
params
のrequire
メソッドでモデルを指定してパラメーターを取得- Railsの慣習として、上記の処理を
private
メソッドとする
params.require
以下のメソッドチェーンで、パラメーターのハッシュが得られる。
params.require(モデル名).permit(キー1, キー2, ...)
今回の例の場合は以下の通り。
params.require(:user).permit(:name, :password)
メソッド化
コントローラーにprivateで以下のメソッドを定義。
1 2 3 4 5 6 7 8 9 |
class PagesController < ApplicationController ..... private def user_params params.require(:user).permit(:name, :password) end end |
データの利用
パラメーターが必要な場合はこのメソッドを呼び出す。たとえばフォーム入力データをコンソールに出力する例として、
1 2 3 4 |
def params_check_process p user_params[:name] p user_params[:password] end |
以下はフォーム入力のコンソールへの出力例。
1 2 |
"yamada" "passyamada" |
permitの意味~ストロングパラメーター
モデルに寄らないフォーム入力の場合params
は単純なハッシュだが、モデルを介した場合は、params
にモデル名をキーとするパラメーターのハッシュが含まれる。
今回の例の場合のparams
の内容は以下の通り。
1 |
<ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"tTwbM.....", "user"=>{"name"=>"yamada", "password"=>"passyamada"}, "commit"=>"登録", "controller"=>"pages", "action"=>"params_check_process"} permitted: false> |
params[:user]
をキーとしたハッシュを取り出すと、フォーム入力が得られる。
1 |
<ActionController::Parameters {"name"=>"yamada", "password"=>"passyamada"} permitted: false> |
そして、この結果はrequire.permit
を通した結果とほぼ同じ。
1 |
<ActionController::Parameters {"name"=>"yamada", "password"=>"passyamada"} permitted: true> |
ただし最後のpermitted
が異なり、params
の場合はfalse
でpermit.require
を通した場合はtrue
になっている。
permitted: false
の場合はデータを一度に保存するマスアサインメントが使用できない。これを許すと、悪意のあるユーザーが不適切なデータを追加して送信し、データベースに書き込まれてしまう恐れがある。
require.permit
による場合はあらかじめ取り扱い可能なデータが限定されているので、permitted: true
に設定され、マスアサインメントが可能となる。