Michael Hartl 教程第 8 章中的会话助手方法
Session Helper Methods in Michael Hartl Tutorial Chapter 8
我正在 Rails 上阅读 Ruby 上的 Michael Hartl 教程,我在理解某些逻辑时遇到了问题。请注意,逻辑是有效的,只是没有引起我对实际发生的事情的共鸣。
在本章中,我们将登录用户并创建会话。这里是辅助方法:
module SessionsHelper
# Logs in the given user.
def log_in(user)
session[:user_id] = user.id
end
# Returns the current logged-in user (if any).
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
# Returns true if the user is logged in, false otherwise.
def logged_in?
!current_user.nil?
end
end
根据用户是否登录,我们根据以下条件更改导航:
<% if logged_in? %>
do something....
<% else %>
do something else...
<% end %>
据我了解,代码通过调用 logged_in 检查用户是否已登录?方法。 logged_in?方法调用 current_user 方法来查看它是否为零。如果它是零它 returns 假,如果它不是零它 returns 真。作为测试,我尝试更改 logged_in?方法如下:
def logged_in?
!@current_user.nil?
end
当我 运行 由于某种原因使用此方法时,在我使用经过身份验证的凭据登录后,@current_user returns 无。为什么是这样?请注意,如果我将它改回原来的 logged_in,这会起作用吗?我只是调用方法 current_user.
的方法
当我提出我的问题时,我发现了这一点。在后一种情况下
def logged_in?
!@current_user.nil?
end
@current_user 尚未设置,因为从未调用过 current_user 方法。为了测试,我将方法更改为以下内容:
def logged_in?
current_user
!@current_user.nil?
end
首先调用方法,然后评估@current_user。它工作没有问题。原始方法有效,因为 current_user returns @current_user 到 logged_in?方法作为用户对象或 nil(@current_user 被设置为方法中的最后一行——它是唯一的一行,因此它隐式地返回到 logged_in? 方法)。
这不是您问题的直接答案,因为您在我尝试回答时已经弄明白了。但我想澄清一些问题。
在 rails 中,实际上大多数 Web 应用程序,我们在服务器 session 中跟踪用户的登录状态。您代码中的 log_in
方法就是这样做的。
然后当新请求进入需要身份验证的控制器时,我们检查会话是否有存储的用户。如果存在,则请求已通过身份验证,否则未通过身份验证。所以,logged_in?
方法的实际职责是检查会话。
然而,我们想要在控制器 and/or 视图中访问经过身份验证的用户的属性是很常见的。所以我们在控制器上设置一个@current_user变量,这样你就可以访问认证用户的用户对象。同样,直接使用实例变量不是一个好习惯。所以我们把它包装在 current_user
方法中。
那你可能会问,为什么我们不把整个用户对象存储在session中呢?因为在会话中存储太多是不好的(参见 here)。所以,我们只存储 id 并使用它从数据库中获取用户。
这里是||= 部分的用武之地。||= 缓存db 的结果。否则,我们每次调用 current_user 方法时都会访问 db。
希望这能澄清实际发生的事情。
我正在 Rails 上阅读 Ruby 上的 Michael Hartl 教程,我在理解某些逻辑时遇到了问题。请注意,逻辑是有效的,只是没有引起我对实际发生的事情的共鸣。
在本章中,我们将登录用户并创建会话。这里是辅助方法:
module SessionsHelper
# Logs in the given user.
def log_in(user)
session[:user_id] = user.id
end
# Returns the current logged-in user (if any).
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
# Returns true if the user is logged in, false otherwise.
def logged_in?
!current_user.nil?
end
end
根据用户是否登录,我们根据以下条件更改导航:
<% if logged_in? %>
do something....
<% else %>
do something else...
<% end %>
据我了解,代码通过调用 logged_in 检查用户是否已登录?方法。 logged_in?方法调用 current_user 方法来查看它是否为零。如果它是零它 returns 假,如果它不是零它 returns 真。作为测试,我尝试更改 logged_in?方法如下:
def logged_in?
!@current_user.nil?
end
当我 运行 由于某种原因使用此方法时,在我使用经过身份验证的凭据登录后,@current_user returns 无。为什么是这样?请注意,如果我将它改回原来的 logged_in,这会起作用吗?我只是调用方法 current_user.
的方法当我提出我的问题时,我发现了这一点。在后一种情况下
def logged_in?
!@current_user.nil?
end
@current_user 尚未设置,因为从未调用过 current_user 方法。为了测试,我将方法更改为以下内容:
def logged_in?
current_user
!@current_user.nil?
end
首先调用方法,然后评估@current_user。它工作没有问题。原始方法有效,因为 current_user returns @current_user 到 logged_in?方法作为用户对象或 nil(@current_user 被设置为方法中的最后一行——它是唯一的一行,因此它隐式地返回到 logged_in? 方法)。
这不是您问题的直接答案,因为您在我尝试回答时已经弄明白了。但我想澄清一些问题。
在 rails 中,实际上大多数 Web 应用程序,我们在服务器 session 中跟踪用户的登录状态。您代码中的 log_in
方法就是这样做的。
然后当新请求进入需要身份验证的控制器时,我们检查会话是否有存储的用户。如果存在,则请求已通过身份验证,否则未通过身份验证。所以,logged_in?
方法的实际职责是检查会话。
然而,我们想要在控制器 and/or 视图中访问经过身份验证的用户的属性是很常见的。所以我们在控制器上设置一个@current_user变量,这样你就可以访问认证用户的用户对象。同样,直接使用实例变量不是一个好习惯。所以我们把它包装在 current_user
方法中。
那你可能会问,为什么我们不把整个用户对象存储在session中呢?因为在会话中存储太多是不好的(参见 here)。所以,我们只存储 id 并使用它从数据库中获取用户。
这里是||= 部分的用武之地。||= 缓存db 的结果。否则,我们每次调用 current_user 方法时都会访问 db。
希望这能澄清实际发生的事情。