多分
def current_user
User.find_by(id: session[:user_id])
end
としてもいいけど、
current_userメソッドが1リクエスト内の処理で何度も呼び出されてしまうと、呼び出された回数と同じだけデータベースへの問い合わせが発生してしまい、結果として処理が完了するまでに時間がかかってしまうからです。
というのが理由ではないですかね?
こちらのトピックで分からないことがあります。
こちらの
#current_userメソッドの定義
def current_user
if session[:user_id]
User.find_by(id: session[:user_id])
end
end
はなぜ、
#ユーザーIDが存在しない場合例外が返る
User.find(session[:user_id])
ではなく
#ユーザーが存在しない場合nilが返る
User.find_by(id: session[:user_id])
とするべきなのでしょうか?
本文より
セッションにユーザーIDが存在しない場合findメソッド使用すると例外が発生する事は理解しました。
また
セッションにユーザーIDが存在しない場合find_byメソッドを使用するとnilが返ることも理解しています。
しかしcurrent_userメソッドでは
if session[:user_id]
...
end
とすることでログインしているユーザーが存在しない場合、自動的にnilが返っているように思います。
それならばif文内が実行されるのはログインしているユーザーがいる時に限られると思うので、その中のコードが
User.find(session[:user_id])
でも
User.find_by(id: session[:user_id])
そこまで変わりがない様に思います。
①
session[:user_id]
には存在する値があるがUser.find(session[:user_id])
に対応するユーザーが存在しないケースがある?
②
#findを使用したcurrent_userメソッドの定義
def current_user
if session[:user_id]
User.find(session[:user_id])
end
end
は、たとえ
if session[:user_id]
...
end
としてif文によってユーザーが存在していることを確かめ、最終的にユーザーを取り出せたとしても単にfindよりもfind_byを使用するべきとされていて相応しくないから?
ご助言お待ちしております。
多分
def current_user
User.find_by(id: session[:user_id])
end
としてもいいけど、
current_userメソッドが1リクエスト内の処理で何度も呼び出されてしまうと、呼び出された回数と同じだけデータベースへの問い合わせが発生してしまい、結果として処理が完了するまでに時間がかかってしまうからです。
というのが理由ではないですかね?
@shun_study_p
Questionersession[:user_id]
には存在する値があるがUser.find(session[:user_id])
に対応するユーザーが存在しないケースがある?
普通はログイン時には存在する User レコードを元にsession[:user_id]
をセットしますし、ユーザーの退会ロジックでは User レコードを消すと同時にセッションも削除します。あまり考慮しなくていいケースではあります。
ただ、実装ミスか何かでそんなケースに陥る可能性はあります。レアケースでだけ current_user
が例外を投げるようになっていると、例外の rescue を忘れがちです。 User.find
は RecordNotFound 例外を投げますから、ユーザーはセッションが切れてそのケースから抜け出すまで(≒ユーザーのクッキーが失効するか自身で消すまで)どのページにアクセスしても404画面に飛ばされることになります。そうなっては困りますね。
def current_user
if session[:user_id]
User.find_by(id: session[:user_id])
end
end
このように User.find_by
を使っておけば、そんなケースでもただ nil
が返るので、ログインしていない状態と同じように処理を続行できます。
セッションがあるのに User オブジェクトがない状態を判別したいからあえて User.find
を使うという選択もあります。そこは実装方針次第です。
@shun_study_p
Questioner