4

I have finished the Ruby on Rails Tutorial by Michael Hartl. I know some basic ideas about instance variable, getters and setters.

The sign_in method is here

def sign_in(user)
  cookies.permanent[:remember_token] = user.remember_token
  self.current_user = user
end

Now I'm stuck at this line

self.current_user = user

I found this related question, but I still don't get it.

After sign_in, the user will be redirected to another page, so @current_user will be nil. Rails can only get current_user from cookie or session, then set @current_user, so that it doesn't need to check cookie or session again in current request.

In sign_out method

def sign_out
  self.current_user = nil
  cookies.delete(:remember_token)
end

For the same reason, why do we need self.current_user = nil since the user would be redirected to root_url?

Here's the code for getter and setter

def current_user=(user)
  @current_user = user
end

def current_user
  @current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
Community
  • 1
  • 1
greenmoon55
  • 81
  • 1
  • 9

3 Answers3

2

You are right that the @current_user is not set after the redirection.

@current_user ||= User.find_by_remember_token(cookies[:remember_token])

This statement helps avoid repeated calls to the database, but is only useful if current_user variable is used more than once for a single user request. Consequently, setting the current user is only helpful during a single call.

Similarly, setting the current user to nil and removing the token from cookies during sign_out ensures that subsequent processing will take the signing out into account. Otherwise, there is a risk of other methods referring current user variable and thinking that the user is still logged in.

Subhash
  • 3,121
  • 1
  • 19
  • 25
1

You have a full explanation on the next section of the book

Current User

Basically when you do self.current_user= you invoque the method 'def current_user= ()' this is the setter, you will be probably not only assigning the @current_user variable here but also keeping some reference in the cookies or session for future reference. In the same way you will probably be creating an accessor that will look like

def current_user
  @current_user ||= get_user_from_cookies
end

In order to have accesible the current user. I think you just went to fast and the book is trying to go step by step for users not familiarised with web dev

Fernando Diaz Garrido
  • 3,995
  • 19
  • 22
  • 1
    Thanks, but I'm a little bit confused. I have already put the token in the cookies in `sign_in` method, so I don't know what to do in the setter. – greenmoon55 Dec 26 '12 at 10:40
  • 1
    Well then you dont have to do anything else, probably the author put it as a setter because it is very likely that you will want to do various things when setting the current user or perhaps just a way to explain how you can overwrite setters – Fernando Diaz Garrido Dec 26 '12 at 12:16
1

I believe you're right in saying that for the code you've written so far it doesn't make much difference.

However it doesn't make sense for your sign_in/sign_out methods to know the ins and outs of how users travel through you application. It would be very brittle (and not its business) if it assumed that the only thing your application did after login was to redirect the user to the root page.

You could be doing all sorts of things, from collecting audit data (record every time someone logs in for example) to redirecting them to a different page depending on the users preferences or some other attribute of the user.

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
  • Now I redirect users to homepage or do other things in SessionsController#create. These codes are not in sign_in/sign_out methods. – greenmoon55 Dec 26 '12 at 10:58