I am having an issue trying to use the cancan authorization. I have users with one role per user, so I added user.role column as suggested in the cancan wiki.
I also have an index view for kindergardens and another index view for children.
What I am trying to achieve is to only allow access to the index views to the corresponding users with role kindergarden or parent (for children).
When I now authorize Kindergardens in kindergardens controller nobody is allowed to access the index view, although I defined it in my ability model.
Help would be much appreciated. I have no idea what I am missing...
Ability model:
class Ability
include CanCan::Ability
def initialize(user)
[...]
elsif user.role == 'kindergarden'
can [:update, :destroy], Kiga do |kiga|
kiga.user_id == user.id
end
can :read, Kiga do |kiga|
kiga.user_id == user.id
end
can :index, Kiga
can :create, Kiga
else
end
Kindergardens controller:
class KigasController < ApplicationController
before_action :set_kiga, only: [:show, :edit, :update, :destroy]
# GET /kigas
# GET /kigas.json
def index
@kigas = Kiga.all
authorize! :index, @kiga
end
You define your abilities as blocks and that needs to have instances. In index actions you have only Active Record scopes, not actual instances.
Btw you have a typo in controller code:
def index
@kigas = Kiga.all
authorize! :index, @kigas # was @kiga that is nil probably
end
The block is only evaluated when an actual instance object is present. It is not evaluated when checking permissions on the class (such as in the index action).
In this case you can use hashes of conditions
can [:update, :destroy], Kiga, user_id: user.id