I wonder if their are a way of using cancan to define abilities depending on role for a specific resource.
For now i have something like this, but the problem is that it goes through each role the user have each time like if he has 2 times the role1 even if it's on different Stuff instances.
def initialize(user)
@user = user || User.new
@user.roles.map(&:name).each{|name| send(name)}
end
def role1
can :manage, Stuff
end
How can i optimize this ?
I've thought about something like:
def initialize(user)
@user = user || User.new
can :manage, Object do |object|
roles = @user.roles.where(resource_id: object.id, resource_type: object.class)
unless roles.empty?
roles.map(&:name).each{|name| send(name)}
end
end
end
But it still got the problem of getting the ":manage" action to any user that have any other ability on the ressource...
So are their any way to access to the resource instance in the initialize function of cancan ?
I've found something for avoiding the :manage using this issue https://github.com/ryanb/cancan/issues/133
so i've added
def current_ability
@current_ability = Ability.new(current_user, @resource)
end
in the application_controller.rb in the controller just before the "authorize!" call i've defined an instance variable named @resource
like so:
def create
project = Project.find(params[:project_id])
@resource = project
authorize! :create_stories, project
....
end
and updated the ability.rb
def initialize(user, resource)
@user = user || User.new
roles = @user.roles.where(resource_id: resource.id, resource_type: resource.class)
if roles.empty?
false
else
roles.map(&:name).each{|name| send(name)}
end
end
def role1
can :go_and_make_coffee
end
so enjoy if it helps someone