目前に迫るテストに向け、復習とロープレに励む もそ。
まだまだ知識的に怪しい部分があるので、毎回へんな汗をかきそうになります...
今回はエラーを解決するための考え方について書いていこうと思います。
##エラー発生!名探偵もそ、出動!
もはやシリーズ化しつつある[名探偵もそ]
脳内BGMは小松未歩もしくは倉木麻衣を再生しながら読んでください。
今回のエラーは**"投稿画面から画像とテキストを投稿したのに、画像だけが反映されない"**というもの。
なんというか、一見するとよくありそうなエラーですよね。
でも実は、ちょっと厄介なエラーなんです。
##なにが厄介なのか?
まずは今回のエラーが起きた流れを考えてみます。
1.新規投稿画面を表示
2.投稿内容を入力
3.ボタンを押して送信
4.投稿内容がDBに保存される
5.DBに保存された投稿内容が一覧ページに表示される
これをMVCの流れで考えてみると、図のようになります。
なのでこの一連の処理のどこかでエラーが起きているというわけです。
とはいえこのファイルを一つずつ見ていくとなると、時間がかかってしまいます。
特にビューファイルはコードの記述量も多く、一行ずつ参照していくのはかなり大変です。
容疑者ファイルがちょっと多いのが、今回の厄介ポイントです。
##どうやって探す?
そこで今回は、処理の流れから範囲を絞る方法でエラーを探していきます。
この考え方ができるようになると、最低限のチェックで素早くエラー箇所を特定することができますよ!
ではさっそく、絞り込み捜査開始!
まずSequelProを起動して、テーブルを確認します。
先ほど投稿した内容が、正しく反映されているか見てみましょう。
テキストの右側がimageカラムなのですが、値がNULLになっています。
つまり投稿された情報がDBに入っていないことが分かります。
処理の流れを逆行してエラーが起きることはないので、この時点でindexのビューファイルでエラーが起きている可能性を除外できます。
次にコントローラのcreateアクション内でbinding.pryを実行します。
binding.pryは、記述された部分までの処理を実行することができます。
さらにターミナルで params と入力すれば、どのような変数が入っているかを確認することができます。
def create
Tweet.create(image: tweet_params[:image], text: tweet_params[:text], user_id: current_user.id)
binding.pry
end
こんな感じで記述して投稿ボタンをクリックしたあとでターミナルの画面を確認すると、コントローラの記述以前の処理の流れは正しく行われているようです。
ということは、newアクションのビューファイルとルーティングではエラーが起こっていません。
これで半分まで絞れました!
さらに先ほどのコンソール画面をよく見てみると、
[2]pry(#Tweetscontroller)> image
でエラーが起きていると書かれています。
今回コントローラ内でimageの記述があるのは、createアクション内とストロングパラメータの中だけなので、その二箇所を見てみます。
private
def tweet_params
params.permit(:text)
end
...ん?
み、見つけたーー!!!
このコードをよく読んでみると、ストロングパラメータ内で許可する値がtextしか指定されていません。
ストロングパラメータは、本来不正な情報の送信(たとえばデータを書き換えるような記述)が送られないよう制御する、セキュリティ強化のための記述です。
ですが今回は、許可するはずのimageの値を記述し忘れたためブロックされてしまい値がDBに保存されなかったようです。
名探偵もそ、見事エラー解決です!
--
さて明日はいよいよ試験があるのですが、復習をしていると
「あー!これそういうことか!」
と納得できる箇所が増えてきました(試験前日でまだそんな状態かよ、というツッコミはなしでお願いします)
果たして明日、もそは一発で試験合格できるのか?!
...続く。