ログイン機能を作る(2) Ruby on Rails

(1)でログイン機能の作成をしたけど、これだけだと結局ログインした人なら全ページ閲覧可能な状態です。各ユーザーの情報などは、本人もしくは管理権限のあるものだけが閲覧、編集できるようにすべきです。つまり、ログインしているユーザーのオブジェクト(情報)を取得する必要があります。

ログインユーザーのオブジェクトを取得できるようにする。

現状:既にログインしているので、session[:user_id]がcookieに残っている。なら、この通行手形は、user.idと同じ番号なので、

User.find_by(id: session[:user_id])

で大丈夫そう。

findを使わない理由

findは、session[:user_id]がまだない場合、例外処理(エラー)が発生してしまう。
これに対し、
find_byは、単にnilを返してくれるので、例外処理が発生しない

ということで、

いやまって、結局、これ毎回データーベースにアクセスする必要あるじゃん!そもそも、毎回チェックするのがいかがなものかってのが主要な命題だったので、本末転倒気味
これは、データベースを覗きにいく回数を減らすもので、そもそも見た目やシステム自体に大きな変更を加えるものではないので、地味な作業なんですよね。

そこで、

一度取得したオブジェクトを変数にしてしまう。

@current_user = User.find_by(id: session[:user_id])
これで、ログインユーザのオブジェクト(情報)は、@current_userに格納されました。
次に、再度取得しなくてもいいようにしないといけない。
これは、取得行為をする前に既に取得済みかどうか確認すれば良い。
if @current_user.nil?
で情報が既に取得済みかどうか聞いてみる。
で、これがまだなら、
@current_user = User.find_by(id: session[:user_id]) 覗きにいく
既に取得済みなら
@current_user = @current_user そのままの情報を格納
def current_user
if session[:user_id]
@current_user ||= User.find_by(id: session[:user_id])
end
end

ログアウト機能を実装する

deleteメゾット

deleteメソッドは、引数で指定した文字を文字列の中から削除し、新しい文字列を返します。

s = "hello, world"
puts s.delete("l")
=> heo, word
session.delete(:user_id)

セッションからユーザーIDを削除しただけではcurrent_userメソッドによって@current_userに代入されたユーザーオブジェクトは削除されません。

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

コメント

タイトルとURLをコピーしました