エラー発生箇所
Railsチュートリアル(第7版)10章にて
現在のユーザーが管理者かどうかを確認するadmin_user
メソッドを追加後Mintestを実行するとエラーが発生しました。
同じような状態になってしまった方の参考に少しでもなれば幸いです。
class UsersController < ApplicationController
.
.
.
# 管理者かどうか確認
def admin_user
redirect_to(root_url, status: :see_other) unless current_user.admin?
end
end
NoMethodError: undefined method `admin?' for nil:NilClass
解決までの思考
Userモデル
にadmin
が追加されていないのかと思い、schema.rb
の内容を確認します。
ActiveRecord::Schema[7.0].define(version: 2023_04_12_041409) do
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "remember_digest"
t.boolean "admin", default: false
t.index ["email"], name: "index_users_on_email", unique: true
end
end
追加されていました。
>> user = User.first
>> user.admin?
=> true
Railsコンソールでadmin?
メソッドが使えることも確認できます。
ということはメソッドを実行するcurrent_user
に問題がありそうです。
admin_user
メソッドはdestroy
アクションが実行される前にbefore_action
で呼び出されるので、その時点でcurrent_userに値が入っている必要があります。
ここで同じくbefore_action
でadmin_user
の前に呼ばれるlogged_in_user
が実行されていないのでは!と閃きました。
logged_in_user
を実行するアクションを指定するonly:
に:destory
を指定し忘れたかと思い確認すると、、
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :delete]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
:destroy
とすべきところを:delete
にしていました、、
:destroy
に修正すると無事テストが通りました!
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
分かったこと
メソッドを実行する対象(今回の場合はcurrent_user
)をレシーバという。
for nil:NilClass
のエラーが出た場合はレシーバがnilになっていないか疑う。
※参考記事
https://hachimaki37.hatenablog.com/entry/2020/12/15/193747
https://diveintocode.jp/blogs/beginner/nilClass