5

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 の本によると、これを行うと、ユーザーのサインイン ステータスが忘れられてしまうため、意味がありません。どうしてそうなるのか???なぜこれを行わず、代わりに上記のより複雑なバージョンを使用するのかを誰か説明してもらえますか?

4

2 に答える 2

2

この線

return @current_user ||= user_from_remember_token

@current_user実際に必要になるまで変数 の初期化を避けるための遅延初期化の形式です。@current_userこの関数が最初に呼び出されたときに初期化されることはありませんが、連続して呼び出されるたびに値が設定されます ( user_from_remember_tokennil 以外の値が返されると仮定します)。

彼は書くことができた

def current_user
  return user_from_remember_token
end

このコードは常に、現在のユーザーを Cookie から読み取ったものに初期化します。これは正しく動作しますが、Cookie を繰り返し読み取らないようにするため、一度読み取りを行い、それを変数に格納します。

彼にはできない

def current_user
  return @current_user
end

@current_user 変数はページ リクエスト間で保持されないためです。ページがレンダリングされてクライアントに送り返された後、@current_user 変数は破棄され、その値は忘れられます。

お役に立てれば。これらのフープを飛び越える必要がある理由の詳細については、Web アプリケーションでの状態の維持を調べてください。

于 2011-06-22T16:00:05.063 に答える
2

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

そのため、ユーザーがサインインしてページを開くと、最初に呼び出されてインスタンス変数に値current_userが入力され、それが以降の呼び出しに使用されます。@current_usercurrent_user

于 2011-06-22T13:23:35.613 に答える