I have Projects resource which is nested in Users resource.
My Cancan Ability class is:
class Ability
  include CanCan::Ability
  def initialize(user)
    #everyone
    can :read, Project
    if user.blank? 
      # guest user
      ...
    else
      #every signed in user
      case user.role
        when User::ROLES[:admin] 
          #only admin role user
          can :manage, :all
        when User::ROLES[:member] 
          #only member role user
          can :update, User, :id => user.id
          can [:create, :update, :destroy], Project, :user_id => user.id
        else
      end
    end
  end
end
And Projects controller:
class ProjectsController < ApplicationController
  load_and_authorize_resource :user
  load_and_authorize_resource :projects, :through => :user, :shallow => true
  ...
end
I have few questions:
Is it possible to deny :read User and allow to :read Project, so that everyone could access /users/10/projects, but not /users/10 or /users?
How can I deny user accessing :new action with other user_id? For example, if I add
#everyone
can :read, User
can :read, Project
this code allows user with id 42 to access /user/41/projects/new.
Solved it by doing:
class Ability
  include CanCan::Ability
  def initialize(user)
    #everyone
    can :read, Project
    can :read, User # required to access nested resources
    cannot :index, User
    cannot :show, User
    if user.blank? 
      # guest user
      ...
    else
      #every signed in user
      case user.role
        when User::ROLES[:admin] 
          #only admin role user
          can :manage, :all
        when User::ROLES[:member] 
          #only member role user
          can :update, User, :id => user.id
          can :manage, Project, :user => { :id => user.id }
        else
      end
    end
  end
end
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With