3

我正在通过伟大的Michael Hartl教程来构建ruby应用程序here在Ruby中创建登录会话时了解“current_user”概念

我想了解如何创建一个会话的概念,我被困在了解这一行:

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]参数。所以我不明白它在哪里。

也有这2种方法在同一模块中:

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全局变量使用在意见?

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

+1

'self'是一个Ruby关键字,允许对象引用自身。因此,'self.current_user = user'正在调用模块的'current_user =(user)'方法,该方法将参数'user'分配给变量'@ current_user'。在你看来,当你调用'current_user'时,你正在调用'current_user'方法,它返回'@ current_user'变量。希望有所帮助。 – 2012-08-15 13:43:12

+0

哦,我刚刚注意到Harti的辅导说的或多或少都是我在我的答案中写的相同的东西......嗯。你不明白他写的是什么吗?这不是明显的东西,需要一段时间才能沉入水中(在写回答时不得不多次复查自己)。 – 2012-08-15 13:49:09

+0

就像Tom L说的那样,self允许一个对象引用自己,并且所有东西都是Ruby中的一个对象。所以'自我'可以指很多东西,比如类的一个实例(当在一个实例方法中时,就像在你的例子中那样),类本身(当在类内但是在外部方法中定义时,比如def self.method), etc. – maru 2012-08-15 13:49:20

回答

4

有几件事情。首先,你正在阅读的方法名称错误(这并不奇怪给出了如何隐藏的ruby方法命名)。 def current_user=(user)实际上被读为定义采用参数user的方法current_user=,而def current_user定义了不采用参数的方法current_user。这些分别被称为settergetters

这里是一个参考:Ruby (programming language): What are setters and getters in Ruby?

这样解释的重复。谈谈你的下一个问题。

我不明白这是什么self.current_user =用户意味着

self本身就是一个话题,对得起自己的讨论,所以我甚至不会试图解释它(这里的one reference)。出于这个问题的目的,要记住,为了设置实例变量,你需要在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一个讨论:Why do Ruby setters need "self." qualification within the class?

UPDATE:小的澄清,有关使用self的制定者的类内的最后一个环节,实际上是有点离题,因为你叫它在一个模块中,而不是直接来自一个类。在模块的情况下,self.current_user = user中的self将成为该模块包含在其中的类,例如, User.current_user如果它被称为类User等内再次,你们自己讨论的另一个话题...

+0

非常感谢你的回复。我花时间回顾你所解释的问题。我理解了制定者和获得者的整个概念。我仍然需要更好地把握“自我”。问题 - 但这将在一个新的线程:) – Alon 2012-08-17 11:42:08

+0

很高兴它对你有意义! “自我”可以是一种令人挠心的,我仍然在学习它的细微差别。 – 2012-08-17 12:13:47

1

方法def current_user=(user)基本上是在sign_in方法,以设定CURRENT_USER使用二传手。

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

self.current_user在sign_in方法的上下文中将引用此例中的调用类或模块。它将从Session Helper模块呼叫current_user