I want to cache a Post
view, but the view depends on the permissions of the current user (e.g., I only show the "edit" link if current_user.can?(:edit, @post)
)
So I'd like my cache key to include a representation of the current user's CanCan abilities, so that I can invalidate the cache when the user's abilities change
SO: how can I get a string that represents the current user's abilities such that 2 different users with the same abilities will generate the same "ability string"?
I've tried user.ability.inspect
, but this doesn't produce the same string for different users who have the same abilities
EDIT: revised for CanCanCan
As of version 1.12 of CanCanCan (the community continuation of CanCan), Ability.new(user).permissions
returns a hash with all permissions for the given user.
Previous answer (CanCan):
This might be a little complex...but here it goes..
If you pass the specified User into the Ability model required by CanCan, you can access the definition of that users role using instance_variable_get, and then break it down into whatever string values you want from there..
>> u=User.new(:role=>"admin")
>> a=Ability.new(u)
>> a.instance_variable_get("@rules").collect{
|rule| rule.instance_variable_get("@actions").to_s
}
=> ["read", "manage", "update"]
if you want to know the models in which those rules are inflicted upon, you can access the @subjects instance variable to get its name..
here is the model layout for Ability from which I worked with (pp)
Ability:0x5b41dba @rules=[
#<CanCan::Rule:0xc114739
@actions=[:read],
@base_behavior=true,
@conditions={},
@match_all=false,
@block=nil,
@subjects=[
User(role: string)]>,
#<CanCan::Rule:0x7ec40b92
@actions=[:manage],
@base_behavior=true,
@conditions={},
@match_all=false,
@block=nil,
@subjects=[
Encounter(id: integer)]>,
#<CanCan::Rule:0x55bf110c
@actions=[:update],
@base_behavior=true,
@conditions={:id=>4},
@match_all=false,
@block=nil,
@subjects=[
User(role: string)]>
]