I am following along with Michael Hartl's rails tutorial. I am confused with a portion of the sessions helper module.
In the following code can someone please clarify if the current_user
in the logged_in?
method refers to the actual method current_user
and is read as the user is only logged_in? if the method current_user
dies not return nil?
OR
Is the current_user
referring to the instance variable @current_user
inside of the current_user
method
Any clarification is greatly appreciated. Thank you so much!
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
if session[:user_id]
@current_user ||= User.find_by(id: session[:user_id])
end
end
# Returns true if the user is logged in, false otherwise.
def logged_in?
!current_user.nil?
end
end
CodePudding user response:
Every module that you put in the app/helpers
directory is included into your controllers. When you include a module you add it to the ancestors chain of the class so it behaves as if the method was defined in the class itself.
So to explain the current_user
method line by line it checks if the session has the user_id
and then assigns the instance variable @current_user
to the controller if its not already set. This is known as a memoizing getter method - and avoids firing a database query to fetch the user every time its called.
In logged_id?
you're using that getter method:
# Returns true if the user is logged in, false otherwise.
def logged_in?
!current_user.nil?
end
It could actually be written as !@current_user.nil?
. But there is a big caveat - in Ruby you can reference instance variables that are not set without error. So if you made a typo and wrote!@curent_user.nil?
it would just fail unexpectedly as its always nil.
When creating an authentication system there should also only be one method that knows how to fetch the user, and all other code should go through that system so that the implementation details don't leak out all over the place.