Railsの基本的なログイン機能

環境:macOS Catalina 10.15.6

Gemを使わない基本的なログインの仕組みについて

構成

Controller: application(include SessionsHelper), sessions, static_pages, users

Model: application_record, user

下記コードを言語化しました。

#sessions_helper.rb

module SessionsHelper

 def log_in(user)
   session[:user_id] = user.id
 end

 def current_user
   if session[:user_id]
     @current_user ||= User.find_by(id: session[:user_id])
   end
 end

 def logged_in?
   !current_user.nil?
 end

 def log_out
   session.delete(:user_id)
   @current_user = nil
 end
end

log_in(user)を使ってsession[:user_id]にuserのidを入れるとlogin状態になってcurrent_userメソッドが使えるようになる。データは保存されていないのでブラウザを閉じるとsessionの中身は基本的に消える。

current_userではsession[:user_id]の中身を確認して存在したら(rubyは存在するオブジェクトはtrueを返す。)@current_userの中身を確認して、@current_userが存在しなかったらデータベースにユーザーのidがsession[:user_id]と同じものを問い合わせて、@current_userに見つかったuserを入れる。

@current_user ||= User.find_by(id: session[:user_id])
#下と同じ
if @current_user
@current_user = @current_user
else
@current_user = User.find_by(id: session[:user_id])
end

User.find_by(id: session[:user_id])をするとデータベースに問い合わせが行く。current_userメソッドが呼び出されるたびにデータベースに問い合わせがいくとその度に時間がかかる(データベースの問い合わせよりrails内で処理できた方が早い?)ので@current_userが存在する時はデータベースに問い合わせしなくて済むように分岐させている。

loged_in?メソッドはcurrent_userメソッド、つまり戻り値である@current_userがnilではないか(存在の確認)をtrueかfalseで返す。@current_userがnilのときはsession[:user_id]が存在していないってことなのでまだlog_in(user)メソッドを行っていないことになる。

log_outメソッドはsessionのuser_idを削除して@current_userにnilを入れている。sessionだけ消せばいいかと思いきや@current_userにすでにUser.find_by(id: session[:user_id])が入っているのでそれだけではログアウト出来ない。@current_userにnilを入れることでlog_in?メソッドはfulseを返し、current_userメソッドもsession[:user_id]がないため@current_user ||= User.find_by(id: session[:user_id])は実行されない。



この記事が気に入ったらサポートをしてみませんか?