我正在浏览关于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的方法。
答案 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?方法)。