Michael Hartl教程第8章中的会话助手方法

时间:2015-07-25 14:54:34

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4

我正在浏览关于Ruby on Rails的Michael Hartl教程,而且我无法理解某些逻辑。请注意,逻辑是有效的,它并没有让我对实际发生的事情产生共鸣。

在本章中,我们将重新登录用户并创建会话。这里有辅助方法:

<% if logged_in? %>
   do something....
<% else %>
   do something else...
<% end %>

根据用户是否登录,我们使用此条件更改导航:

def logged_in?
  !@current_user.nil?
end

据我了解,代码通过调用logged_in来检查用户是否已登录?方法。 logged_in?方法调用current_user方法来查看它是否为零。如果它是nil则返回false,如果它不是nil则返回true。作为测试,我试图更改logged_in?方法如下:

{{1}}

当我出于某种原因运行此方法时,在使用经过身份验证的凭据登录后,@ current_user返回nil。为什么是这样?请注意,如果我将其更改回原始的logged_in,这是否有效?我只是调用方法current_user的方法。

2 个答案:

答案 0 :(得分:1)

这不是你问题的直接答案,因为你在我试图回答时已经弄明白了。但我想澄清一些观点。

在rails中,实际上大部分是Web应用程序,我们在服务器的session中跟踪用户的登录状态。代码中的log_in方法可以做到这一点。 然后,当新请求进入需要身份验证的控制器时,如果存在用户,我们会检查会话。如果它存在则请求被验证,否则它是未经身份验证的。因此,logged_in?方法的实际职责是检查会话。

但是,我们想要在控制器和/或视图中访问经过身份验证的用户的属性是很常见的。因此,我们在控制器上设置@current_user变量,以便您可以访问经过身份验证的用户的User对象。同样,直接使用实例变量不是一个好习惯。所以我们将它包装在current_user方法中。

然后你可能会问,为什么我们不在会话中存储整个用户对象?因为在会话中存储太多是不好的(见here)。因此,我们只存储id并使用它来从db获取用户。

这里是|| =部分的来源。|| =缓存db的结果。否则,每次调用current_user方法时我们都会命中db。

希望这可以澄清实际发生的事情。

答案 1 :(得分:0)

在我提出问题时,我想出了这一点。在后一种情况下

def logged_in?
  !@current_user.nil?
end

@current_user尚未设置,因为从未调用过current_user方法。为了测试,我将方法更改为以下内容:

def logged_in?
  current_user
  !@current_user.nil?
end

首先调用该方法,然后评估@current_user。它没有问题。原始方法有效,因为current_user将@current_user返回给logged_in?方法作为用户对象或nil(@current_user被设置为方法中的最后一行 - 它是唯一的一行,因此它被隐式返回到logged_in?方法)。