Question

I currently have the following situation:

  • One enterprise has many projects
  • One enterprise has many users
  • One project has many users
  • One user has many roles on different projects

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!

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top