Reputation: 1726
I currently have the following situation:
This was modeled with the table Assignment, which has project_id, role_id, user_id.
There are four roles: Administrator, Observer, User, Guest.
I'd like to give permission based on the role I have for certain project, however with CanCan I receive only my user and not the project I'm standing at, so I have no idea how to give permission based on users only.
This is my current code, which is defenitely not correct, but it has worked for now.
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can [:activate], User
can [:show,:index,:project_summary, :add_stage],Project
# only if the user is logged in
if user.id!=nil
can [:create,:update,:edit],Project do |p|
(user.assignments.where(project_id: p.id,role_id: 1,user_id: user.id).any? || user.assignments.where(role_id: 1,user_id: user.id).any? )
end
can [:show,:update, :add_user], Enterprise do |e|
user.assignments.where(role_id: 1,user_id: user.id).any?
end
can [:show],Enterprise do |e|
user.enterprise.id==e.id
end
# can only update if its his own
can [:show,:edit, :update], User, id: user.id
end
end
The problem is that now I want to give the ability to an "Administrator" of a project to give add new users to the project (which means creating an Assignment) and this can only be achieved if I know what project I'm standing at plus the my user.
If anyone could help me out and explain how can I achieve this having a "triple" relation (Project - User - Role), I'd really appreciate it.
Thanks!
Upvotes: 2
Views: 906
Reputation: 634
You need to verify the role based on user, and project. So you need to overwrite the ability method which can go in the ApplicationController or set it from others controller which are requiring permission.
def current_ability
@current_ability ||= Ability.new(current_user, params[:project_id]) // Or params[:id]
end
You can do something like above.
You then can get the role from here
Assignment.find_by(user.id: self.id, project.id: project_id).role.name
In case you have a name in the role method.
Upvotes: 2