rails current user
March 13th, 2010
While playing with next app I thought a bit about so common current_user … so a lot of tutorials and descriptions uses this method in application controller.
After thinking a while I found other way to do this, and for me it looks a bit better, any thoughts on it ?
So get started with User model:
class User < ActiveRecord::Base acts_as_authentic cattr_reader :current end [/sourcecode] Now in application controller add filter to set current user: [sourcecode lang="ruby"] class ApplicationController < ActionController::Base before_filter :set_user private def set_user current_user_session = UserSession.find User.send :class_variable_set, :@@current, current_user_session > current_user_session.record end end
Now you can use whatever you want the same method to access current user:
User.current
Added 2010.03.14 :
Warning please do not use this method it is not thread safe – it is only good for single threaded applications.
@Giulio Turetta is right, I forgot about that fact, but it might change in future releases so better would be to use sentient_user or Thread.current[] for storage – just to be safe for future
Isn’t rails in not threat mode by default?
If you don’t use config.threadsafe! your way is safe. I’m wrong?
User the sentient_user rubygem:
http://github.com/bokmann/sentient_user
If you have a current_user in your ApplicationController, it will use thread local variables to give you a User.current method, as well as this_user.current? (useful for permissions) and this_user.make_current methods, which is useful for simulating logged in users in tests.
by using a thread local variable, the technique used by sentient_user is thread safe.
You both are right, in the prototype stage I did not cared about thread safety. Thanks for the hint, I have to go back till It is not to late.
AFAIK doing the way you’re doing is not thread safe.
On every request, a new instance of the controller is created. For that request instance variables like current_user are kept safe from other request.
Moving that to class variables remove the thread safety the previous scenario give to you.
Concurrent different users will be identified as same or erratically being switch as the application will have one one place where the current user is defined.
Hope that helps.
Won’t @@current be set to the last person who accessed the site? It’s a class variable, and they’re nothing but scoped global variables. So there’s ONE for the whole site (or, more likely, ONE per Mongrel instance). It feels to me like there’s a race condition just waiting to play havoc with your user permissions!