1

大家!最近,我正在研究 Michael Hartle 的 RoR 教程。在第 8 章中,我遇到了一个困扰我两天的问题。这是问题所在。在第 8.2.3 节中。

module SessionsHelper

  def sign_in(user)
    .
    .
    .
  end

  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user     # Useless! Don't use this line.
  end
end

迈克尔写道:

如果这样做,我们将有效地复制 attr_accessor 的功能,我们在第 4.4.5.5 节中看到了它。问题是它完全无法解决我们的问题:使用清单 8.21 中的代码,用户的登录状态将被遗忘:如用户一转到另一个页面——噗!——会话将结束,用户将自动退出。为了避免这个问题,我们可以通过代码清单 8.19 中的代码创建的记忆令牌找到对应的用户,如代码清单 8.22 所示。

清单 8.22。

module SessionsHelper
  .
  .
  .
  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user ||= User.find_by_remember_token(cookies[:remember_token])
  end
end

我的问题是:为什么以前的代码会在用户转到新页面时自动注销会话?为什么第二段代码不会?我认为,只要用户登录,@current_user 的值将始终为“用户”,直到他明确注销,对吗?

4

2 回答 2

2

前面的代码并没有将用户注销,也没有在后续请求中重新创建用户。

状态不会在请求之间共享,并且必须在每个请求中重新创建。@current_user是一个实例变量,并在单个请求的持续时间内保持它的值。

为了绕过状态不共享的事实,对于每个请求,我们需要重新加载必要的变量,例如@current_user从会话中常见的变量中加载,在这种情况下,它们正在使用remember_tokencookie。

第一段代码不会@current_user在每个请求上重新加载,因此一旦用户登录后浏览到另一个页面就会忘记它持有的值,第二段代码尝试通过remember_tokencookie 加载当前用户,所以在这之后当有人登录时设置,应该记住用户,直到该 cookie 过期。

于 2012-08-22T02:34:33.447 回答
1

他在这里说的是,当我们在第一个示例中使用@current_user 而不是在登录页面上时,我们没有调用@current_user = User.find(1)。我们依赖它已经设置好了。由于我们没有明确设置 @current_user 如下:

@current_user ||= User.find_by_remember_token(cookies[:remember_token])

表示如果 @current_user 未设置,则通过使用存储在 cookie 中的 id 查找用户来设置它。这样,当我们导航到没有明确设置 @current_user 的页面时,它将被填充。

于 2012-08-22T02:35:15.637 回答