我将在第4版的Michael Hartl的Rails教程的第8.4.4节(“两个微妙的错误”)中加入一些代码。 (链接到文本的这一部分:https://www.railstutorial.org/book/log_in_log_out#sec-two_subtle_bugs[1])
具体来说,我对以下文字/代码感到困惑:
“第二个微妙之处在于用户可以登录(和 记住了)在多个浏览器中,例如Chrome和Firefox 如果用户在一个浏览器中注销而不是,则会导致问题 其他。例如,假设用户在Firefox中注销 将remember digest设置为nil(通过代码清单8.38中的user.forget)。 这仍然适用于Firefox,因为在log_out方法中 代码清单8.39删除了用户的id,因此用户变量为nil 在current_user方法中:
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
结果,表达式
由于短路评估,
user && user.authenticated?(cookies[:remember_token])
返回false。“
对于这个问题,让我们坚持使用Firefox而不用担心第二个浏览器错误。哈特尔似乎在说以下内容:
user && user.authenticated?(cookies[:remember_token])
短路。 我的问题是如何发生这种情况。如果log_out方法按照规定工作,那么后续调用中的行elsif (user_id = cookies.signed[:user_id])
是否应该为false? elsif块不会运行,用户变量永远不会被设置。实际上,current_user方法中的两个条件都是false,并且该方法将返回nil。根据用户变量不会出现短路。
他描述的短路评估可以进行吗?
答案 0 :(得分:1)
你是正确的,因为
没有发生短路elsif(user_id = cookies.signed [:user_id])
未运行且用户变量永远不会设置为 IN FIREFOX。,因为Cookie已在Sessions Helper中删除:
# Forgets a persistent session.
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
# Logs out the current user.
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
然而,这并没有改变Hartl的主要观点,即用户也是通过 Chrome 登录的,这是发生错误的地方。
答案 1 :(得分:0)
Hartl最近编辑了本书的那一部分(截至2015年3月初),现在他描述它的当前方式似乎没有这个错误。