I have a working ability defined as below:
routes.rb
resources :projects do
resources :tasks
end
ability.rb
can [:manage], Project, invites: {supplier: {:user_id => user.id}}
can [:new, :create], Task
can [:update, :show, :destroy, :edit], Task, user_id: user.id
Tasks Controller:
load_and_authorize_resource :project
load_and_authorize_resource :task, :through => :project
This properly lets the user create a task, if they are invited to a project.
However, I don't want the user to be able to :manage the project. I just need the user to be able to index the project as below.
ability.rb
can [:index], Project, invites: {supplier: {:user_id => user.id}} ## breaks when changing :manage to :index here
can [:new, :create], Task
can [:update, :show, :destroy, :edit, :index], Task, user_id: user.id
When I put in the the abilities above, the user can no longer access or perform any actions on the task. How do I create a task ability through the project, with only giving an :index ability to the project?
You should probably define that a user can read
a Project when invited. Therefore:
a user can read a project if is invited ( I guess the condition invites: { supplier: { user: user} }
defines an invited user )
can :read, Project, invites: { supplier: { user: user} }
then you have to say that a user can create Tasks for projects to which he got invited, then:
can [:new, :create], Task, project: { invites: { supplier: { user: user} } }
in the end you define that the user can manage his own tasks on projects he his invited to:
can :manage, Task, user: user, project: { invites: { supplier: { user: user} } }
You can also simplify the conditions by extracting
invited_to = { invites: { supplier: { user: user} } }
can :read, Project, invited_to
can [:new, :create], Task, project: invited_to
can :manage, Task, user: user, project: invited_to