Railsチュートリアルの8章のリスト1-6に出てきたログイン中のユーザーを返す処理について、特にコードを省略してる部分がわかりにくかったので自分用にまとめます。
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:user_id)
end
end
end
##ログイン中のユーザーを返す処理
まず、log_in(user)メソッド内の**session[:user_id]**という表現に戸惑いますが、sessionはRailsで事前に定義されているメソッドです。session[:user_id] = user.idを実行するとユーザーのブラウザ内の一時cookieに暗号化済ユーザーIDが自動で作成されます。
current_userメソッド内では奇妙なif文が書かれていますが、まず、ログイン中のユーザーがいる場合をif session[:user_id]で判定します。ここまではわかります。
その直後に、つまりログイン中のユーザーが存在すると判定した場合、@current_user ||= User.find_by(id:user_id)という省略記法が入ってきます。これが難しい。
この記法を分解すると以下のコードになります。これは見覚えのあるコードではないでしょうか。
if @current_user.nil?
@current_user = User.find_by(id: session[:user_id])
else
@current_user
end
@current_userがnilだった場合にUser.find_byメソッドを使い中身を@current_userに代入します。nilではなかった場合、つまり中身が入っていた場合は@current_userをそのまま使います。
このように分解したコードを省略すると次のようになります。
@current_user = @current_user || User.find_by(id: session[:user_id])
||はOR演算子です。@current_userがnilであればUser.find_byメソッドが実行されます。また、@current_userに中身が入っていればtrueとなり、次のUser.find_byは実行されず処理は終了します。(当たり前ですが)省略前と同じ処理ですね。
もう1段省略したコードが最初に紹介したもので、この記法が王道とのこと。
@current_user ||= User.find_by(id: session[:user_id])
2つめの@current_userが省略されて、さらに条件が||=と不思議なことになっています。
この記法になる理屈としては、x = x + 1という変数に加算する式をx += 1と書き換えることができることと同じということですが、まさに上の加算式と同様に慣れるしかなさそうですね。
##まとめ
今回は@current_user ||= User.find_by(id:user_id)の記法がテーマの記事でしたが、地味にsession[:user_id] = user.idも戸惑う点でした。
この省略記法に関しては慣れるしか無いのも厄介なところです。というかRubyは()や{}とか筆頭に省略するところが多くて、ちゃんと処理を追おうと思ったら結構頑張らなければいけませんね。
わざわざuser.find_byを使ってデータ取り出して@current_userに入れる理由ですが、メソッド呼び出しを繰り返し呼び出すことを避けるためです。こうすることで処理速度の効率化につながるとのこと。