帮助方法中的实例变量是否在每个请求之间持续存在?

时间:2017-07-19 03:01:59

标签: ruby-on-rails

我正在开发Ruby on Rails应用程序,并在Michael Hartl找到了一个有用的教程(Ruby on Rails Tutorial(Rails 5))。 我现在正在第8章,我们正在从头开始开发一个简单的登录/注销功能。

在本教程中,将创建一个帮助程序模块以检查用户是否已登录。这是在header.html.erb partial中的每个请求上调用的,以便确定要在标题中显示的链接。

module SessionsHelper

  #Logs in the given user
  def log_in(user)
    session[:user_id] = user.id
  end

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

  def logged_in?
      !current_user.nil?
  end

end

无论如何,作者描述这一行用于防止每次发出请求时都必须查询数据库中的用户记录(仅在用户登录时为第一个请求)

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

这对我来说很有意义,但我注意到在服务器的控制台中,在每次请求之后,仍在查询数据库以查找用户的记录,因为@current_user总是被重置为nil。 所以我的问题是,这是正常的吗? @current_user变量在请求之间不存在,所以我觉得有些不对劲。谢谢:))

1 个答案:

答案 0 :(得分:2)

你做得恰到好处并得到了正确的结果!

  

作者描述此行用于防止每次发出请求时都必须在数据库中查询用户记录

检查此处的措辞。作者可能会说的是,无论调用current_user方法多少次,数据库查询只会按每次请求进行一次。

您看到的模式称为memoization,是以下形式的简写形式:

  def current_user
    if @current_user.nil?
      @current_user = User.find_by(id: session[:user_id])
    end
    @current_user
  end

您实际上并不希望此变量在请求之间保持不变,因为这意味着如果新用户加载了该页面,他们就会获得旧用户的User对象。这正是你不想要的!