迈克尔·哈特尔 第 8.3 章注销会话



我正在阅读迈克尔·哈特尔的 Ruby on Rails 教程,第 8.3 章注销会话,我不明白删除session[:user_id]如何删除@current_user

以下是会话控制器:

class SessionsController < ApplicationController
  def new
  end
  def create
    user =User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in(user)
      redirect_to user
    else
      #flash.now will only flash once - if a new request or view is rendered,the flash will go away now
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end
  def destroy
    log_out
    redirect_to root_path
  end
end

以下是登录和注销帮助程序的会话助手:

module SessionsHelper
    def log_in(user)
        session[:user_id] = user.id
    end
    def current_user
        #find the user if @user is not defined yet, or else, just keep the current user
        #that way we dont have to do a database search every time current_user is called
        @current_user ||= User.find_by(id: session[:user_id])
    end
    def logged_in?
        !current_user.nil?
    end
    def log_out
        session.delete(:user_id)
    end
end

我的理解方式是,一旦@current_user在登录后被定义,即使session[:user_id]已被删除,变量是否仍然存在,因为它被设置为自身?

@current_user ||= User.find_by(id: session[:user_id])

据我所知,没有任何操作删除了@current_user变量。但是当我在调试器期间对其进行测试时,我可以看到一旦有人注销,@current_user就会变得nil

有人可以向我解释机制吗?

会话在请求之间持续存在。 但实例变量@current_user只保留一个请求的长度。 当destroy操作重定向到root_path时,即加载根页面的新请求的开始。

您可能想尝试一下,以便看到从会话中清除user_id不会清除实例变量:

def destroy
  # Test code to initialize @current_user
  current_user
  Rails.logger.debug("@current_user before: #{@current_user.inspect}")
  log_out
  # Test code to check @current_user after updating session
  Rails.logger.debug("@current_user after: #{@current_user.inspect}")
  redirect_to root_path
end

然后检查最终在log/development.log. @current_userlog_out后仍然存在,但它会在请求结束时消失。

最新更新