スクールでの頻出エラー

2022年3月16日

[スクールでよくある質問] undefined method 〇〇 for nil:NilClass (NoMethodError) のエラーとは

学習時の状況やレベル

  • 学習時期: 2ヶ月目
  • 受講生がすでに学んでいること: 基本文法を一度学んだ

こんにちは!

DIVE INTO CODEの齊藤です!

今回は受講生さんの質問でよくある、"undefined method 〇〇 for nil:NilClass (NoMethodError)"のエラーを紹介します。

スクールでのとある質問やりとり

Controllerで定義したインスタンスメソッドをeach文で展開するとき、アソシエーションメソッドをつけるとundefined methodになってしまいました…

該当のエラー

<%= blog.user.email %> ActionView::Template::Error (undefined method `email' for nil:NilClass)

BlogとUserにアソシエーションで関連付けしているようですね!ちょっと詳しくみてみましょう。

お願いします!

このエラーが発生した時、コードの中のどこが怪しいと思いましたか?

エラー文では、emailメソッドが未定義と言われてるので、どこかでemailメソッドを定義すれば良いのでしょうか…?

エラー文を読み解こうとする姿勢は素晴らしいですね!ただ、もう少し慣れる必要がありそうですね。

emailメソッドをnameメソッドに変更してみるとか…?

一旦undefined method emailから離れましょう!このエラーで大事なのは、undefinedと言われているメソッドのレシーバです!

レシーバって、なんでしたっけ…?

レシーバとは、メソッドを実行する対象を指しています!今回の場合、emailメソッドを実行する対象はuserです!

そうでした!

このuserがnilになっていて、かつnilクラスの中にemailメソッドは定義されていないからエラーが発生した、ということです。

確かに、nilに対してemailメソッドは使えないかも

それでは、なぜuserはnilになってしまっているのか?

blogに対してアソシエーションメソッドであるuserを使用した結果がnil… つまりアソシエーションの設定うまくできていないのかも

その通りです!アソシエーション設定をする前のblogデータが残ってしまっているのかもしれません。

あ、確かに投稿者不明のBlogがありました!削除したらさっきのエラーが出なくなりました!

今回と同様のエラーが発生したら、今後はメソッドのレシーバがnilになっていないか確認してみましょう!

ありがとうございました!

まとめ

  • undefinedと言われているメソッドのレシーバを調べる
  • エラー文を読み解こうとする姿勢をもつ
  • アソシエーションの設定を確認する

この技術についてさらに深く学びたい方は 1週間無料! DIVER Learnings アソシエーションシリーズで学習できます。是非ご利用ください。

DIVE INTO CODEのことをもっと知ってみませんか?