Arale

アパレル、バリスタを経て未経験からのプログラマーになった男の勉強ログ

Ruby on Railsにおける記述のアウトプット2

【議題】フォームで入力したデータを送信したが、ページに反映されない。

エラー画面が出ないので、パラメーターやバリデーションの問題と考えられる

①保存する時にターミナルに出力されるログは以下

Processing by CalendarsController#create as JS
  Parameters: {"authenticity_token"=>"aqNYAP4QTakFCz7lLT+lSaKANNhh5Nxes+Yl/9dYGlTfa0wBc8EYEvh2voO/AOx0j2L4Bv5gvs2FOg4t0iaoQQ==", "plan"=>{"date"=>"2020-04-29", "plan"=>"aaaaa"}, "commit"=>"保存"}
Completed 400 Bad Request in 7ms (ActiveRecord: 0.0ms | Allocations: 774)

ActionController::ParameterMissing (param is missing or the value is empty: calendars):
  1. param is missing or the value is empty: calendarsというエラー文が気になる。
  2. callerndarsというキーのバリューが空だ、と書いてある
  3. またHTTPステータスコードは400が表示されてるので、リクエストが失敗している可能性もある。

calendarsというキーはどこのコードのどの部分なのか?が今回の怪しいポイントです。

 

②binding.pryを使って原因を追求しよう

今回の問題箇所は、Railsの基本機能の「フォームからの値を保存」処理です。

処理の流れは以下の通りです。

  1. form_withを利用して整理した情報をフォームからリクエストする
  2. リクエストを受け取ったRailsアプリは、今回はcalendars_controllerのcreateアクションを動かす
  3. createアクション内 Plan.create(plan_params)が動く
  4. 終了

binding.pryを使えば、上記の流れのどの場面でも途中で止め、その後の処理を1つ1つ確かめることが出来る。今回はcreateアクション内部にbinding.pryを記入する。

def create
  binding.pry
  Plan.create(plan_params)
  redirect_to action: :index
end

この状態でサーバーを動かし、実際に保存を試すとbinding.pryを記入した所で止まる。

次に行われる処理がplan_paramsメソッドなので、動作が止まったコンソール上に「plan_params」を打ち込み、Enterを押す。

「paramの中は空だよー」というエラーが出てくる。

 

今回のエラーを解決する上で、コントローラー、モデル、ビューファイルを見てみた。

検索も兼ねて見比べてみると、コントローラーのplan_paramsが引数となっているprivateの所が怪しい…

そもそもcalendersのキーはどこにもないので、params.require.(:calenders)は誤りであること。までは分かった。

が、ここからが非常に長かった。requireの後に続くのが、plansもしくはplanの二つだろうと思ってたので入力するも値が返ってこない…

requireの記述を丸々消して、params.permit(:data, :plan)にしたら、新たなエラーが出たけど何かtrueとは返ってくる…どうしたらいいて思ってたら単なる記述ミスでした。

params.require(:plan).permit(:data, :plan)

そう、この「:」をずっと忘れてました。

そして一番初めのターミナルのエラーで何だったら答えは出てたという。

"plan"=>{"date"=>"2020-04-29", "plan"=>"aaaaa"}, "commit"=>"保存"}

エラー文を直前のではなく、もう少し上のも見るよう意識します…

ストロングパラメーターのおさらい

データを指定したものしか保存できないようにしましょーよ!というストロングパラメーター。マトリョーシカのように入れ子になってます。

params.require(:plan).permit(:data, :plan)

今回だとこんな感じ。「.」は「の」みたいな感じで解釈すると分かりやすいかも。

paramsのplanのdataとplanしか保存しないよー!てことになります。