I'm going in circles with a bit of code in section 8.4.4 ("Two Subtle Bugs") in the 3rd edition of Michael Hartl's Rails tutorial. (Link to this section of the text: https://www.railstutorial.org/book/log_in_log_out#sec-two_subtle_bugs[1])
Specifically I'm confused about the following text/code:
"The second subtlety is that a user could be logged in (and remembered) in multiple browsers, such as Chrome and Firefox, which causes a problem if the user logs out in one browser but not the other. For example, suppose that the user logs out in Firefox, thereby setting the remember digest to nil (via user.forget in Listing 8.38). This would still work in Firefox, because the log_out method in Listing 8.39 deletes the user’s id, so the user variable would be nil in the current_user method:
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
As a result, the expression
user && user.authenticated?(cookies[:remember_token])returns false due to short-circuit evaluation."
For this question, let's stick with Firefox and not worry about the second browser bug. Hartl seems to be saying the following:
- The log_out method sets the remember digest to nil in the database.
- The log_out method deletes the user_id stored in both the session and cookie.
- A subsequent call to the current_user method from within the same browser would not raise an error because "the user variable would be nil in the current_user method." This would cause short-circuiting of the expression
user && user.authenticated?(cookies[:remember_token]).
My questions is how this could ever happen. If the log_out method works as stated, shouldn't the line elsif (user_id = cookies.signed[:user_id]) be false on subsequent calls? The elsif block wouldn't run and the user variable would never be set. In fact both conditionals in the current_user method would be false and the method would return nil. There would be no short-circuiting based on the user variable.
Can the short-circuit evaluation that he describes take place?