プログラミング学習記録

主にRuby on Railsを使ったプログラミングを学んでいます。

バグ修正 Rails入門②

8月1日は、Rails入門②の課題「バグと友達になろう」とHTTP演習をした。 復習のため学習内容をまとめてみる。
まずエラー修正課題だが、解決できていなかったエラーを書き出してみると、
1 NoNameError undefined local variable or method 'about_url'
2 NoMethodError undefined method 'log_in'
3 Failure パスワードが空欄でログインできないという旨の内容

解決の為に試みた事

3はソースコードを確認するとparams.require(:user).permit(:name, :email, :password_confirmation)となっており、ストロングパラメーターに:passwordが抜けていることが原因だとわかった。慣れていない為、関係していそうなコントローラーやビューのコードとしばらくにらめっこしてようやく発見。


1はまずroutes.rbを見てみるとget 'static_pages/about'はあるが、アクションを呼び出すto: 'static_pages#about'がない。 これを記載しなくてもページは表示できるんだっけ?いやできなかったはず……つまり、ここは間違いだな。しかし、get 'static_pages/about'なわけだから、このままだと/static_pages/aboutというURLになるはず。about_urlというヘルパーメソッドで指定できない。routes.rbを書き換えるべきか、テストコードをabout_static_pages_urlにするべきなのか……。
また、about.rbはあるがこれではページの表示はできないのでは?(後から振り返ればここを修正しようとしてファイルの名前をabout.erbに変更していたが、これは間違いで正しくはabout.html.erbだった。確認大事。)
さらにstatic_pages.controller.rbにaboutアクションがないぞ? →追加する
よし、これで動くはず →動かず(前述の事が原因)


2は、log_inなんてメソッドどこにも定義されてないぞ?よしlog_inメソッドをわざわざ定義しなくてもsession[:id]をuser.idに入れればいいのかな? →テスト通らず(実は見つけられなかっただけでhelpersフォルダ内のsession_helper.rbに定義されている。また、session[:user_id]とするべきだった。)


以上こんな方法でバグ修正していては全く効率的ではなく無駄に時間がかかる上、見落としも起きてしまうだろう。
解答の動画があるのだが、エラーを特定していく過程がとてもスマートで効率的で感動した!目からウロコが落ちた。ので、その方法を自分なりに言語化して復習しようというのが今回の本題!

エラー修正の心得

  • テスト実行時のエラーメッセージとソースコードだけ見て進めない
  • ブラウザの検証ツールを使う
  • binding.irb
  • grep -r 検索したいワード ディレクトリ とターミナルでコマンドを打つと、指定したディレクトリ以下にあるファイルで検索したいワードを全体検索

例えば、3のログインできないケース。
まず実際にブラウザでログインを試す。→より詳しいエラーメッセージが表示される。 (実際にブラウザで試すメリット!)
それによるとパスワードが空欄、パスワードが規定文字数以下 とのこと。 パスワードが正しく送信できているかを確認する必要がある。ここでブラウザの検証ツール(ディベロッパツール)の出番だ。
ネットワークタブでフォームから送信された内容を確認できる。(その他にも様々なことを確認できるので使わない手はない)
viewのフォームからの送信は問題ないとわかる。つまり送信された情報がsaveできていないということ。
saveを実行する手前で一旦処理を止め検証する。ソースコードをエディタなどで開き、saveをする行の直前にbinding.irbと加える。それからまたブラウザでログインしてみると、saveする直前で処理が止まり、その時点での@userを出力させたりできる。
こうして実際にアプリケーションの挙動を探っていく事で、どうすればいいかわからない場合でもエラーの原因を探ることができる。

メモ

  • command + option + I でディベロッパツールを開ける
  • .valid?インスタンスがバリデーションを通るか確認
  • pryなどのバグ修正に役立つGemをインストールしてもよいが、binding.irbは元々Railsに入っているので便利
  • VSCodeで全体検索をかけるときは、command + shift + F
  • 空のメソッドを定義するときは、def メソッド名; endと一行で書くことで空であると明示でき、他の人がソースコードを読んだ時に誤解が生じにくい