John
John

Reputation: 634

CanCan allow actions only if the current_user was associated with a project

I am using cancan for authorisation, and I would like to make some restrictions based on a many to many relationship.

Entities

 User - has_many project_assignments
 User - has_many projects, through: :project_assignments

 User - has_many roles, through: :project_assignments

ProjectAssignment: user_id, project_id, role_id

I want to give the user the ability to do a full CRUD on Project and Toy models, only if the project was created by the user. Toy is nested under Project

Toy has many Projects and Project has many Toy through ProjectToy

 if user.role? :moderator
   can :crud, [Project, Toy]
 end

I think I only need to restrict the project, because toy is depending on the project_id, can I do this?

Upvotes: 1

Views: 160

Answers (2)

John
John

Reputation: 634

I found a solution:

In my Project controller I have added:

load_and_authorize_resource through: :current_user

In my Toy controller I added:

load_and_authorize_resource project, through: :current_user load_and_authorize_resource :toy, through: :project

In my Ability file:

if user.role? :moderator
   can :crud, :all or [Project, Toy]
end

And everything is working fine, I`ve assigned a user to multiple projects, and it has access to each project.

Upvotes: 1

Rachel9494
Rachel9494

Reputation: 824

I would try to use some kind of if statement for the second many to many:

can :crud, Project do |project|
  ProjectAssignment.where(user_id: user.id, project_id: project.id).any?
end

can :crud, ProjectToy do |project_toy|
  ProjectAssignment.where(user_id: user.id, project_id: project_toy.project.id).any?
  if can? :crud, ProjectToy
    can :crud, Toy do |toy|
      ProjectToy.where(toy_id: toy.id).any?
    end
  end
end

PS - You may need to be careful with :crud and replace this with [:edit, :update, :destroy, :delete] then give a separate can to :create because if the user is creating a project/toy for the first time then the system won't find any toys or projects associated with him/her and not provide access.

Upvotes: 2

Related Questions