2011-06-22 16 views
5

Michael HartlのRuby on Railsチュートリアルの "Remember Me"の実装を理解するのに問題があります。彼は次のことを含む、ログインするための方法でSessionsHelperモジュールを作成します。Rails - "remember me"ケイパビリティ

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 

注:Userモデルにおけるauthenticate_with_salt方法は、最初のパラメータ(ID)によってユーザを見つけ、ユーザーがある場合そのsaltが2番目のパラメータ(salt)に等しい場合、ユーザが返されます。そうでない場合はnilが返されます。

すでにユーザが署名されている場合は、我々がテストするために、このような長さに行くなぜ私は悩みの理解を持っています

:ユーザーがログインした場合には

@current_userすでにsign_in方法によって定義され、したがって、current_userメソッドの|| =は無意味です。 【:remember_token】ゼロとなり、User.authenticate_with_saltが渡されるユーザーが署名されていない、current_user方法で|| =オペレータがuser_from_remember_tokenメソッドによって返される値を返すが、cookies.signedのでた場合には

[nil、nil]引数を指定してnilを返すので、current_userメソッドはnilを返します。要するに

、それが定義されている場合current_user方法は@current_userを返している場合はnil、それ以外の場合は、単に従来のアクセサメソッドを使用するためにはるかに簡単ではないでしょう。

def current_user 
    return @current_user 
end 

マイケル・ハートルの本はと言いますユーザーのサインイン状態が忘れられるため、これを行うことは役に立たないでしょう。なぜそれは事件だろうか?誰かが私たちがこれをしない理由を説明し、代わりに上記のより複雑なバージョンを使用することができますか?

答えて

2

ライン

return @current_user ||= user_from_remember_token 

それが実際に必要になるまで@current_user変数の初期化を避けるために、遅延初期化の一形態です。 @current_userは、この関数が初めて呼び出されたときには決して初期化されませんが、連続して呼び出されるたびに値を持ちます(user_from_remember_tokenがnil以外を返すと仮定します)。

彼は、このコードは常にそれがクッキーから読み込む何に現在のユーザーを初期化します

def current_user 
    return user_from_remember_token 
end 

を書かれている可能性があります。これは正しく動作しますが、おそらくCookieを繰り返し読み込まないようにしたいので、一度やり、変数に格納します。@current_user変数は、ページ要求には保存されませんので、

彼は

def current_user 
    return @current_user 
end 

を行うことはできません。ページがレンダリングされてクライアントに送り返されると、@ current_user変数は破棄され、その値は忘れられます。

これが役に立ちます。これらのフープを飛び越す必要がある理由の詳細については、Webアプリケーションの状態を維持することに注目してください。

2

sign_inは、実際にログインフォームを使用してサインインする場合にのみ呼び出されます。その後、リクエストごとにCookie値を使用して現在のユーザーを設定する必要があります。

ユーザーがサインインしてページを開くときに初めてcurrent_userが呼び出されると、@current_userインスタンス変数にデータが入力され、さらにcurrent_userコールに使用されます。

+0

しかし、@ current_userがsign_inによって設定された後は、そこにはいないのですか?なぜ、私たちは単にクッキーの代わりにインスタンス変数@current_userを使用できないのですか?彼らの主な違いは何ですか? – Kvass

+0

マイケル・ベナブル氏の答えによると、「@current_user変数はページリクエストを超えて保持されない」だから、ページリクエストで 'current_user'メソッドを初めて使うときは、そのクッキーからユーザ情報を取得する必要があります。 – vesan

関連する問題