I have a feature where an admin can ‘Sign In As’ a customer. The feature works by setting a session variable when the admin switches to a different user and then signing in as the customer using the sign_in(user)
helper in Devise.
Based on this: How To Masquerade As Another User To See How They Use Your App
# users_controller.rb
def become
user = User.find(params[:id])
if impersonating?
session[:admin_id] = nil
else
session[:admin_id] = current_user.id
end
sign_in(:user, user, bypass: true)
redirect_to root_url, notice: "Now signed in as #{user.full_name}"
end
# application_controller.rb
def impersonating?
session[:admin_id].present?
end
helper_method :impersonating?
Problem: I use CanCan for abilities and I’m stuck on how to give admin abilities to a customer when it’s actually an admin signed in as a customer. Basic abilities might be:
# ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
if user.type == 'Admin'
can :manage, Product
end
if user.type == 'Customer'
can :read, Product
end
end
end
What I’d like to do is something like this but I know I can’t access the impersonating?
helper inside the model:
if user.type == 'Customer'
can :read, Product
can :destroy, Product if impersonating? # <-
end
I tried using a virtual attribute and setting user.impersonating
so I could check it in the ability model:
if user.type == 'Customer'
can :read, Product
can :destroy, Product if user.impersonating? # <-
end
but the attribute doesn’t carry across requests.
The only other way I can think of is to create a real model attribute and write user.impersonating
to the database, which I don’t really want to do.
What else can I try?