LoginSignup
0
0

More than 1 year has passed since last update.

[Rails]deviseのuser_signed_in?メソッドが常にfalseを返す不具合への対処法。

Last updated at Posted at 2022-04-03

Railsで転職活動用のポートフォリオ作成中です。
deviseのuser_signed_in?メソッドが正常に動作しない不具合が発生しました。

不具合詳細

確かにログインできているのに、user_signed_in?が常にfalseを返す。

console
...
     8:       <% binding.pry %>
 =>  9:     <% if user_signed_in? %>
    10:       <p>ユーザー詳細です。</p>
    11:       <p><%= link_to "ログアウト", destroy_user_session_path, method: :delete %></p>
    12:     <% end %>
...
$ user_signed_in?
=> false

前提事項

・macOS Monterey v12.1
・ruby v3.0.3
・Rails v6.1.4.4
・devise 4.8.1

その他
・自作のユーザー認証機能のdeviseへの置き換え途中に発生したエラー
・自作の認証機能は、ほぼRailsチュートリアルのコピー

原因

自作のcurrent_userメソッドがsessions_helperに残っており、その実行結果(nil)をuser_signed_in?メソッドが参照してfalseを返していた。

参考(英語):

対策

以下のcurrent_userメソッドを削除(コメントアウト)する。
(Railsチュートリアルを参考にしてきた場合は、おそらくsessions_helperに記載がある。)

before

app/helpers/sessions_helper.rb
module SessionsHelper
  ...
  # 記憶トークンcookieに対応するユーザーを返す
  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user&.authenticated?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end
  ...
end

after

app/helpers/sessions_helper.rb
module SessionsHelper
  ...
  # 記憶トークンcookieに対応するユーザーを返す
  # def current_user
  #   if (user_id = session[:user_id])
  #     @current_user ||= User.find_by(id: user_id)
  #   elsif (user_id = cookies.signed[:user_id])
  #     user = User.find_by(id: user_id)
  #     if user&.authenticated?(:remember, cookies[:remember_token])
  #       log_in user
  #       @current_user = user
  #     end
  #   end
  # end
  ...
end

考察

なぜcurrent_userのコメントアウトのみでuser_signed_inの不具合も改善されたのか。

特にdeviseメソッドの中身を調べたわけではないので予想に過ぎませんが、diviseのuser_signed_inメソッドはcurrent_userメソッドの実行結果を参照しているのでなないでしょうか。
今回発生した不具合に関係する処理の中にcurrent_userはありませんでした。しかし、自作のcurrent_userが実行され、中身を見てみたところnilが入っていました。

console
...
    13: def current_user
    14:   if (user_id = session[:user_id])
    15:     @current_user ||= User.find_by(id: user_id)
    16:   elsif (user_id = cookies.signed[:user_id])
    17:     user = User.find_by(id: user_id)
    18:     if user&.authenticated?(:remember, cookies[:remember_token])
    19:       log_in user
    20:       @current_user = user
    21:     end
    22:   end
    23:   binding.pry
 => 24: end

[1] pry(#<UsersController>)> current_user
=> nil

user_signed_inメソッドが、「current_userの中身がnilならユーザーはログインしていないだろう」と判断していた説。

まとめ

同じ名前のメソッドには要注意。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0