こんにちは、Nanayakuです。
今回は、私が体験した「NoMethodError・nil:NilClass」の原因を紹介します。
目次
NoMethodError・nil:NilClassとは
そもそも「NoMethodError・nil:NilClass」は、なぜ起きるのかと言うと、クラス(userやmicropostなど)で定義されていないmethod(indexやcreateなどのアクション)を使用しようとしているからです。
nilとは、何も存在しない事を表すオブジェクトです。
簡単に言うと、「ボールをバットで打とうとバッターボックスに入ったけど、バットを持っていないですよ」、と教えてくれている状態です。
Control・Viewのスペルミス
「NoMethodError・nil:NilClass」が起こる最も多い原因が、Control・Viewのスペルミスです。
定義したアクションと違うものを書いているので、存在しないのは当たり前ですよね。
エディターの予測変換機能は非常に便利ですが、1度間違えて打ってしまうとそれを予測してしまうため、スペルミスが大量に発生する可能性があるため、注意が必要です。
スペルミスと似ていますが、コードの書き方を間違えている場合もあります。
私は、下のツイートのようなミスをしていました。
自分は、「micropost」を「micropst」にしていたり、controllerでメソッドを定義する時のendの位置がおかしかったことがありました。
繰り返し処理の「each」が定義されていないと出た時は、焦りました😓 pic.twitter.com/PiCVIAJVvc
— Nanayaku@techbooster (@789__PQ) August 19, 2019
メモ
ここで出てくるアクションとは、「def メソッド名 ・・・end」と同じ意味で使用しています。
定義する前に使用している
アクションのプログラムの書き方やスペルミスが見当たらない時は、定義前のmethodを使用している可能性が高いです。
実際に自分がした失敗を例に説明します。
私は、画像のようにUserテーブルとProfileテーブルに分けて、ユーザー登録した後にプロフィールを作成する仕様でプログラムを書きました。
ここで私は、UserテーブルとProfileテーブルを1対1のアソシエーション(関連付け)したので、ユーザー登録後そのユーザーのIDのカラムが出来ると勘違いしていました。
そのため、登録後のマイページで
<% @user.profile.userimage.nil? %>
と、Profileが何も定義されていないのに、「プロフィール画像がない場合」と定義されていないもので条件分岐を書いてしまいました。
本来であれば、
<% if @profile.nil? %>
と、最初にprofileがあるかで条件分岐する必要がありました。
まとめ
「NoMethodError・nil:NilClass」が出た時に確認すること
- Control・Viewでスペルミスがないか探す
- Controlでコードの書き方が間違えていないか見直す
- そのページで対象のアクション(method)が定義されているかインスタン変数の流れ(順番)を意識して見直す
最後に
備忘録がわりに作ったので、間違っている所とかあったら、コメントくれると嬉しいです。