はじめに
Railsチュートリアル8章 8.2.2の意味がよくわからなかったので、自分なりにまとめてみる。概要としては、以下の通りだ。
@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
このような書き方はよく使うらしい。
実現したいこと
最初は@current_user = User.find_by(id: session[:user_id])
でデータを取得する。
それ以降は、取得していた@current_user = { name: "Example User", .. }
の値をそのまま流用する。
コードの分析
今までの書き方を使うと
if @current_user.nil?
@current_user = User.find_by(id: session[:user_id])
else
@current_user
end
最初(中身が何もないとき)だけ@current_user
にUser.find_by..
を代入する。
それ以降は@current_user
の中身があるのでそのまま@current_user
を返す。
短く書くと
@current_user = @current_user || User.find_by(id: session[:user_id])
直訳すると、「@current_user
は@current_user
またはUser.find_by..
である」だが、これだけではよくわからないので、処理の流れとして捉える。
||
は項を左から順に判定し、trueになった時点で処理が終了するので、以下のようになる。
1回目
@current_user =
@current_user # 最初の時点ではnilなのでfalse
||
User.find_by(id: session[:user_id]) # 中身があればtrueを返す
2回目以降
@current_user =
@current_user # @current_userに値が代入されているので、true
||
User.find_by(id: session[:user_id]) # 既にtrueの項があるので、これはスルーされる
さらに短く書くと
@current_user ||= User.find_by(id: session[:user_id])
a = a + 1
をa += 1
で表すことができるのと同じ理論(厳密には違うらしいが)。