Trying to get Cancan securing a few models in an application and curious why it’s not working the way I thought it would. I had thought you could can? on the specific instance as opposed to the entire class so, not in this example but, you could enable abilities on a per instance basis as a list of posts are displayed?!?
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role? :admin
can :manage, :all
elsif user.role? :moderator
can :manage, Post
else
can :read, :all
end
end
end
# posts/index.html.haml
...
- if can? :update, @post <- doesn't work
- if can? :update, Post <- works
Edit: add PostsController.rb
#posts_controller.rb
class PostsController < ApplicationController
before_filter :login_required, :except => [:index, :show]
load_and_authorize_resource :except => [:create]
def index
# @posts = Post.all ## <- handled by Cancan's load_and_authorize_resource
@events = Event.where("end_date <= :today", :today => Date.today)
@next_event = Event.next
respond_to do |format|
format.html # index.html.erb
format.json { render json: @posts }
end
end
...
end
This line:
Is asking CanCan “can I update this specific post.” You defined the ability in terms of all posts. If you had done:
Then your “if can?” would work, and the user would only be able to update their own posts. So you want to use the specific resource version (“@post”) if something about this instance of the resource determines the permission, and you want to use the class version (“Post”) if the user has the ability for all instances of the class.