4

我正在阅读很棒的 Michael Hartl 教程来在这里构建 ruby​​ 应用程序。

我试图理解如何创建会话的概念,但我一直在理解这一行:

self.current_user = user

在这种方法中:

module SessionsHelper

  def sign_in(user)
    cookies.permanent[:remember_token] = user.remember_token
    self.current_user = user
  end
end

我了解使用 user_token 创建 cookie 的整个概念。

但我不明白是什么 self.current_user = user 意思,为什么还要保留这行代码——我有带有令牌的 cookie——为什么我需要知道当前用户?

此外,这个“自我”存储在哪里 - 它不像flash[:success]我可以在我的一个视图中看到的参数。所以我不明白它在哪里。

同一模块中还有这两种方法:

  def current_user=(user)
    @current_user = user
  end

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

我仍然试图将这个神秘的目的点点滴滴联系起来current user——它的目的是创建@current_user全局变量以在视图中使用吗?

如果是这样 - 为什么有这两个重复的功能def current_user=(user)def current_user

4

2 回答 2

5

一些东西。

首先,您读错了方法名称(考虑到 ruby​​ 方法命名的神秘程度,这并不奇怪)。def current_user=(user)实际上被解读为定义current_user=带参数的方法user,而def current_user定义current_user不带参数的方法。它们分别称为settergetter

这是一个参考:Ruby(编程语言):Ruby 中的 setter 和 getter 是什么?

所以这解释了重复。关于你的下一个问题。

我不明白 self.current_user = user 是什么意思

self本身就是一个话题,值得自己讨论,所以我什至不会尝试解释它(这是众多参考中的一个)。就这个问题而言,重要的是要记住,为了设置实例变量,您需要在分配前加上self,即使在类中也是如此(对于其他目的,它是隐式的)。该行的其余部分是对current_user=我上面提到的 setter 方法的调用,带有参数user.

为什么甚至有必要保留这行代码 - 我有带有令牌的 cookie - 为什么我需要知道当前用户?

之所以有必要,是因为您不希望每次需要获取当前用户时都从令牌中查找用户。看一下getter方法:

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

这就是说:如果我还没有查找并设置实例变量@current_user,那么请查找它;如果我已经设置它,那么只需返回它。这样可以节省很多查找时间。

我认为这回答了你的问题。有很多更深层次的问题(self等),您可以在其他地方找到更多信息。这里有一个关于为什么需要self在 SO 上包含在 setter 中的讨论:为什么 Ruby setter 需要“self”。班级内的资格?

更新:小澄清,关于self在类中使用设置器的最后一个链接实际上有点离题,因为您是在模块中调用它而不是直接从类中调用它。在模块的上下文中,selfinself.current_user = user将成为模块包含在其中的类,例如,User.current_user如果它在 class 中被调用User,等等。同样,另一个讨论主题......

于 2012-08-15T13:38:44.417 回答
1

该方法def current_user=(user)基本上是一个 setter,sign_in 方法使用它来设置 current_user。

def current_user将返回@current_user,或者如果未设置,它将通过remember_token 在Users 表中找到它。这基本上允许您在任何时间点获取 current_user。

self.current_user在这种情况下,在 sign_in 方法的上下文中将引用调用类或模块。它将current_userSession Helper模块调用。

于 2012-08-15T13:49:07.540 回答