Reputation: 3311
In my app I have two types of users (User
and Shop
now, will add Admin
soon) which are authenticated through the same auth strategy, and thus are stored in the same current_profile
variable. So, it could be an instance of several models, that's why I'm fetching it with following method:
class ApplicationController < ActionController::Base
before_action :fetch_current_user
private
def fetch_current_user
if session[:current_profile_type].blank?
@current_profile = nil
return
end
case session[:current_profile_type]
when 'Shop'
model = Shop
when 'User'
model = User
end
@current_profile = model.find_by(id: session[:current_profile_id])
end
end
But I'm unhappy with this solution, it looks like too noisy for me. Maybe there is a better/simpler approach?
P.S. I don't like to use constantize
here: while be more readable it'll slow down every app's request.
Upvotes: 0
Views: 48
Reputation: 12643
Here is one possibility
class ApplicationController < ActionController::Base
PROFILE_TYPES = {
'Shop': Shop,
'User': User
}
before_action :fetch_current_user
private
def fetch_current_user
profile_type = PROFILE_TYPES[session[:current_profile_type]]
@current_profile = profile_type && profile_type.find_by(id: session[:current_profile_id])
end
end
Or how about caching the results of constantize
? That way you do not need to manually maintain a Hash map like in the example above.
class ApplicationController < ActionController::Base
before_action :fetch_current_user
private
def fetch_current_user
profile_type = (self.class.cached_profile_types[session[:current_profile_type]] ||= session[:current_profile_type].constantize) # Constantizes each type only once after each application boot.
@current_profile = profile_type && profile_type.find_by(id: session[:current_profile_id])
end
def self.cached_profile_types
@@cached_profile_types ||= {} # Cache across all subclasses of ApplicationController
end
end
Upvotes: 1