Passing params to CanCan in RoR
In ApplicationController add the following:
# CanCan - pass params in to Ability# https://github.com/ryanb/cancan/issues/133def current_ability @current_ability ||= Ability.new(current_user, params)end
The most current answer is in the CanCan wiki: https://github.com/ryanb/cancan/wiki/Accessing-Request-Data
can
takes two arguments: first is type of action that user is trying to perform on a resource, second is resource (can be class name or instance variable) itself. If you have your Ability set correctly, you should be able to do something like this:
def show if params[:format].eql?("pdf") // do something elsif params[:format].eql?("csv") if can? :read, resource #do stuff end endend
Don't forget that you have to have your user authenticated before running any CanCan checks.can?
method only returns true or false. I normally like to use authorize!
method to check abilities. Unlike can
, it would rise CanCan::AccessDenied
error that you can rescue and process gracefully. Something in the lines of:
#models/ability.rbclass 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? :hiring_manager can [:read, :update], Post, user_id: user.id end end end#controllers/posts_controller.rbclass PostsController < ApplicationController::Base before_filter :authenticate_user def show @post = Post.find(params[:id]) authorize! :read, @post # will thorow an exception if not allowed endend
Then, I just catch the exception on ApplicationController level.