I'm relatively new to rails (3), and am building an application, using CanCan, where there are 3 tiers of users.
My ability is bog-stock right now, copied from cancan docs, basically defining the guest role and the admin role
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # Guest user
if user.is_admin?
can :manage, :all
else
can :read, [Asana,Image,User,Video,Sequence]
end
end
end
I'm looking to add in the user role. Since I'm creating that throwaway user model, I thought about using new_record? to determine if the user is logged in or not. Something like:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # Guest user
if !user.new_record? and user.is_admin?
can :manage, :all
elsif !user.new_record? and !user.is_admin?
can {registered user-y permissions}
else
can :read, [Asana,Image,User,Video,Sequence]
end
end
end
But, it just doesn't feel right. Seems kind of disassociated from, like, actual logged-in-ed-ness, and have concerns about whether its actually secure.
Looking for advice on a more elegant way to doing this.
Thanks!
Good question, I use a lower to higher permissions approach:
class Ability
include CanCan::Ability
def initialize(user)
# Guest User
unless user
can :read, [Asana,Image,User,Video,Sequence]
else
# All registered users
can {registered user-y permissions}
# Admins
if user.is_admin?
can :manage, :all
end
end
end
end
This way if tomorrow you have other roles to integrate you can do it adding a case statement like so:
class Ability
include CanCan::Ability
def initialize(user)
# Guest User
unless user
can :read, [Asana,Image,User,Video,Sequence]
else
# All registered users
can {registered user-y permissions}
# Different roles
case user.role
when 'admin'
can :manage, :all
when 'manager'
can :manage, [Video, Image, Sequence]
end
end
end
end
So what you basically want is abilities for none logged in users, abilities for a logged in user and then abilities for a logged in admin?
Because the current user model is passed into the initialize you're going to have to test based on a property of the user and it would make sense to use a basic role property stored on the user model, eg
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role == 'admin'
# Admin roles
can :manage, :all
elsif user.role == 'user'
# Signed in user permissions
else
# Guest permissions
can :read, :all
end
end
So when a user signs up/registers you can default the role value to 'user' and then allow for some method to update this to 'admin' in a management interface. You could use a single admin? check on a user since this would be false for guests as well as normal logged in users.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With