0

This is the line I don't quite get.

@_current_user ||= session[:current_user_id] &&      User.find(session[:current_user_id])

If there is a User model with an email field and a password field what is User.find looking for? ie there is no session field stored in the User model.

x6iae
  • 4,074
  • 3
  • 29
  • 50
  • `User.find` expects an integer (the user id to look for), `session` is an object that you can store values in (like a hash) and retrieve them between requests. so you're extracting the user id from session and passing it to `User.find` – Amr Noman Dec 13 '15 at 08:15

2 Answers2

0

Session has to do with the controller in your application.

A session is a way to store information (in variables) to be used across multiple pages. Unlike a cookie, the information is not stored on the users computer.

Sessions are usually saved as a key: value hash pair, and they can get expired.

so, according to the code example you gave:

@_current_user ||= session[:current_user_id]
User.find(session[:current_user_id])

The line: @_current_user ||= session[:current_user_id] is setting the @_current_user to the value of current_user_id in session, if @_current_user is nil.

User.find(session[:current_user_id]) on the other hand is getting the value of current_user_id in session, which should be an id, and is going to the database to find the user with that id.

So, User.find(session[:current_user_id]) is finding by id, and not by email or by password

x6iae
  • 4,074
  • 3
  • 29
  • 50
0

@current_user is meant as an instance variable to bring back the User object for the currently logged-in user.

The typical use case for @current_user (at least to Devise users like us) is to utilize it within our code infrastructure:

def create
   @model = current_user.models.new ...
end

Thus, the answer to your question:

what is User.find looking for?

... is that it's looking for the User object for the signed-in member.

I think you're getting confused with how an authentication system would be expected to work. Namely that once you log in (authenticate), the app sets a session (as described by Sunny K) to denote which user is browsing.

This is why you have User.find(session[:current_user_id]) -- your authentication system (whether homebrew or pre-packed) has already validated the email & password. Now it has to keep track of which user you are, so that each time you send a request, it can rebuild your current_user object.

--

Another important factor is the fact that HTTP is "stateless" - meaning that each request has to be "new" (IE the state has to be recreated each time).

This is opposed to a stateful application, such as a game, where the fact you're running the application allows you to retain its state throughout the session.

As such, when Rails receives requests from the browser, it does not "remember" who you are - it's literally a dumb machine.

If you want access to user-specific information, there needs to be a way to firstly authenticate the user (which you have), and then authorize their request. The authorization part is up to you, but in order to make it work, you basically have to send the current user id to the app each time.

Then, when you invoke an instance of your program, the @current_user object will be available. This is what User.find(session[:current_user_id]) is for.

Richard Peck
  • 76,116
  • 9
  • 93
  • 147