所以我正在关注Rails Tutorial,并且我已经到达了我们想要使用sign_in SessionHelper签署用户的部分。
问题1 :
module SessionsHelper
def sign_in(user)
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
current_user = user
end
def current_user=(user) #set current_user
@current_user = user
end
def current_user #get current_user
@current_user
end
我遇到困难的部分是:
问题在于它完全无法解决我们的问题:使用代码时,用户的登录状态将被忘记:用户一进入另一页面。
我不明白这是怎么回事?我继续阅读并了解添加的代码,确保@current_user永远不会为零。但是我没有看到如果我们刚刚在第5行建立了current_user将如何恢复为nil。
问题2 :
更新的代码如下:
module SessionsHelper
def sign_in(user) #in helper because used in view & controller
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
current_user = user
end
def current_user=(user) #set current_user
@current_user = user
end
def current_user #get current_user
@current_user ||= user_from_remember_token #<-- short-circuit evaluation
end
private
def user_from_remember_token
User.authenticate_with_salt(*remember_token) #*=use [] instead of 2 vars
end
def remember_token
cookies.signed[:remember_token] || [nil, nil]
end
end
在remember_token帮助器中,为什么它使用cookies.signed []而不是cookies.permanent.signed []&amp;为什么不使用我们刚刚了解的|| =运算符?
问题3 :
为什么我们需要authenticate_with_salt?如果我认证&amp; sign_in可以看到id&amp;来自传递给它的用户的salt属性,为什么我们需要double_check呢?什么样的情况会引发混乱?
答案 0 :(得分:4)
请记住,@current_user
等实例变量仅在请求期间设置。控制器和视图处理程序实例专门为一次和一次渲染而创建。
通常很容易假设,因为你已经在某个地方设置了一个变量,它将在未来的某个时刻继续工作,但事实并非如此。要在请求之间保留某些内容,您需要将其存储在某个地方,最方便的地方是session
工具。
这个例子中缺少的是:
def current_user
@current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
通常,最好使用写访问器来映射您给出的sign_in
方法的功能作为示例:
def current_user=(user)
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
@current_user = user
end
当分配当前用户的行为与暗示相同时,有一种特定的“登录”方法,这很奇怪。
从风格问题来看,当一个用户正在查看另一个用户时,调用这些方法session_user
而不是current_user
可能更有意义。 “当前”可能表示“我正在查看的用户”或“我当前登录的用户”,具体取决于您的观点,这会导致混淆。 “会话”更具体。
<强>更新强>
在回复您的附录时,使用cookies
阅读和cookies.permanent
分配的原因与使用flash.now
分配和flash
阅读的大致相同。 .permanent
和.now
部分旨在用于执行赋值运算符。