Michael Hartl による Ruby on Rails チュートリアルの「Remember Me」の実装を理解するのに苦労しています。彼は、以下を含むサインイン用のメソッドを含む SessionsHelper モジュールを作成します。
module SessionsHelper
def sign_in(user)
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
current_user = user
end
def current_user=(user)
@current_user = user
end
def current_user
return @current_user ||= user_from_remember_token
end
private
def user_from_remember_token
#passes array of length two as a parameter -- first slot contains ID,
#second contains SALT for encryption
User.authenticate_with_salt(*remember_token)
end
def remember_token
#ensures return of a double array in the event that
#cookies.signed[:remember_token] is nil.
cookies.signed[:remember_token] || [nil,nil]
end
end
注: authenticate_with_salt
User モデルのメソッドは、最初のパラメーター (id) によってユーザーを検索します。ユーザーが定義されていて、そのソルトが 2 番目のパラメーター (salt) と同等である場合、ユーザーが返されます。それ以外の場合は nil が返されます。
ユーザーが既にサインインしているかどうかをテストするために、なぜそんなに長い時間を費やすのか理解できません。
ユーザーがサインインしている場合@current_user
、メソッドによって既に定義されているsign_in
ため、メソッド内の ||=current_user
は無意味です。
ユーザーがサインインしていない場合、メソッドの ||= 演算子はcurrent_user
メソッドによって返された値を返しますuser_from_remember_token
が、cookies.signed[:remember_token] は nil でUser.authenticate_with_salt
あるため、[nil,nil] 引数が渡されます。そして nil を返すため、current_user
メソッドは nil を返します。
つまり、current_user
メソッドが定義されている場合は @current_user を返し、それ以外の場合は nil を返す場合、従来のアクセサー メソッドを使用する方がはるかに簡単ではないでしょうか。
def current_user
return @current_user
end
Michael Hartl の本によると、これを行うと、ユーザーのサインイン ステータスが忘れられてしまうため、意味がありません。どうしてそうなるのか???なぜこれを行わず、代わりに上記のより複雑なバージョンを使用するのかを誰か説明してもらえますか?