あっという間の十年ブログ【Ruby篇】

"詮ずるところ#{プログラミング}は、ただ年月長く倦まずおこたらずして、はげみつとむるぞ肝要にて、学びやうは、いかやうにてもよかるべく、さのみかかはるまじきことなり。いかほど学びかたよくても、おこたりてつとめざれば、功はなし。また、人々の才と不才とによりて、その功いたく異なれども、才不才は、生まれつきたることなれば、力に及びがたし。されど、大抵は、不才なる人といへども、おこたらずつとめだにすれば、それだけの功は有る物なり。" - 本居宣長

undefined method `session_token' for nil:NilClass

いつもの如くしこしことRailsチュートリアルやってたら、11章くらいで急に嫌~な感じのエラーが出て、半日失った。一応解決済み。

ローカルサーバーでlocalhost:3000に入ろうとしたら、以下のエラーが出た。

undefined method `session_token' for nil:NilClass

session_tokenが定義されていない…?

問題の箇所
app/helpers/sessions_helper.rb

  def current_user
    if (user_id = session[:user_id]) 
      user = User.find_by(id: user_id)
      @current_user ||= user if session[:session_token] == user.session_token
    elsif (user_id = cookies.encrypted[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

見ると、session_tokenはちゃんと定義されていたので、session_tokenのレシーバであるuserがおかしいという推測が立つ(この推測が立つまで3時間くらいかかった)。このサイト(「undefined method 〇〇 for nil:NilClass (NoMethodError) のエラーとは」)のおかげ。

問題の箇所の前にdebuggerをおいて挙動を確かめる。

      user = User.find_by(id: user_id)
      debugger
      @current_user ||= user if session[:session_token] == user.session_token

user.session_tokenは当然nilなのだが、user_idに105が代入されていた。

User.countするとデータベースに100人しかいなかったので、考えられる可能性は、

・幽霊の可能性

・パスワードをブラウザのsession(Cookie)に記憶させた後でユーザーを削除したため、ログインしているのにユーザーの実体がない(ためエラーが起きる)、という変な感じになっている。

(つまり、session[:user_id]は残っている(105番)のだが、ユーザーの実体がないので、User.find_by(id: user_id)で探しても見つからず、userがnilになってしまっている)

実際に他のブラウザ(Edge)で試したら普通に入れたので、そういうことだと思う(幽霊じゃなかった)。

ChromeCookieの削除の仕方調べとこ。

追記)ChromeからlocalhostCookie消したら入れた。

(あとは、ユーザーが存在しないにもかかわらずブラウザのcookieが残ってしまっている場合は、cookieを削除する、という処理を書いておけばいいかな~。)