【エラー対応Rails編】undefined method ‘〇〇’ for nil:NilClassの対応方法

エラー文の翻訳

NilClassのnilオブジェクトに対して、〇〇メソッドがないよ!

問題があったコード

では、問題のコードを見てみましょう。

class BoardsController < ApplicationController
    before_action :authenticate_user!

==途中コード省略==
    def show
        @tasks = @board.tasks
    end
==途中コード省略==
end

Boardを押すと、それに紐づくTaskの一覧が表示されるような設定です。
ちなみにBoard has many Tasks&Task belongs to Boardの関係になっているとします。

このコードで一覧が表示されるか確認してみると、下図のようなエラーが出ました。

tasksメソッドに問題があるわけではなく、その前の@boardが原因です。エラー文は、@boardがnilだよ!と教えてくれているわけです。

本来showメソッドは、その対象のidを指定しなければいけません。これはルートを見れば分かります。

@boardとだけ書いていたので、コントローラーは「どのidのボードの詳細画面にいけばいいんだ?」と迷ってしまいます。

では、どうすればboardのidを指定できるのでしょうか?

修正したコード

class BoardsController < ApplicationController
    before_action :authenticate_user!

==途中コード省略==
    def show
        @board = Board.find(params[:id])
        @tasks = @board.tasks
    end
==途中コード省略==
end

@boardがnilなので、@boardが何かを定義してやればOKです。
全ボードから、id(主キー)に対応するBoardの情報を探せるように、findメソッドとparams[:id]を使っています。

ここで、findについて復習しておきます。

findメソッドとは?

Activerecordの基本的な検索手段で、主キーによる検索を担当します。
find(key)のようにキーを引数に指定すれば使用可能。例)find(2)
複数のキーによる検索も可能。

次にparams[:id]の復習です。

params[:id]とは?

idキーの値を取得するできる。

ちなみにparams[:board_id]のように書く場合もあります。これはキーが主キーか外部キーの違いかで使い分けます。

例えば、今回のようにBoardモデル(テーブル)が自分自身が持つキー(主キー)で検索するので単に:idと書くだけでOKです。

@board = Board.find(params[:id])

しかし、Boardモデルが別のモデルのキー(例:idなど)を使って、Boardモデル内を検索する場合は、params[:外部モデル名_id]のように書かなければいけません。

例えば、Boardモデル内をUserモデルのuser_idという外部キーを使って、検索する場合は下記のようなコードとなります。

@board = Board.find(params[:user_id])

余談1 @の意味を考えて使おう

余談ですが、@boardと指定するのは、View側に@boardの値を渡して、表示させる必要があったからです。

なんでも間でも@をつけるんじゃなくて、その値をView側で使うのか?を考えると良いでしょう。(自戒を込めて書いています)

余談2 モデル同志のリレーションができているか確認しよう

今回は問題なかったのですが、モデル同志が紐づいていないためにエラーが起こることもあります。

例えば、先程のコードを使って説明します。

@board = Board.find(params[:user_id])

これはBoardテーブルの中をuser_idというキーを使って検索するという意味でした。でも、これはBoardテーブルにuser_idというカラムがないと検索できません。

なので、モデル同士のリレーションができているか、DBとActiverecordの状態を確認すると良いかと思います。(再び自戒を込めて書いています)

DB:schema.rbでBoardモデルにuser_idというカラムがあるか確認
Activerecord:has_manyやbelongs_toで紐づいてるか確認


しっかりとエラー文を読むことは大切ですね!
以上です。

参考文献

[Rails初心者必見]Rails あるあるのエラーを解説 – Qiita

Webアプリケーションを作成して行く段階でエラーが出るのはつきもの! そのなかで、いかにエラーとしっかり向き合うかが重要かと個人的には思っております! 今回は、あるあるのエラーを何個か抜粋して解説していきます。 2020/04/19 編集点 ↓ Loggerの使い方 を追記しました。 例えば、すごく簡素的な例ですが、 みたいなコードがあったとしましょう! このとき、 undefined method ‘update’ for nil:NilClass とエラーが出たと仮定します! この意味としては、 NilClassの nilオブジェクトに対して、 update メソッドは定義されていないよ!ってことです。 つまり、@tweetが nil になっているということです! findメソッドは、見つからなかった場合に nil オブジェクトを返します。 そのため、このような簡素的なコードでは、エラーが起こりにくいかもしれませんが、 Usecasesや Servicesなどのようにディレクトリを分岐させていった時に直面するので、 findメソッドを使った時は、@tweet.present?

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です