Passing params to CanCan in RoR

主宰稳场 提交于 2019-12-04 05:03:44
cailinanne

In ApplicationController add the following:

# CanCan - pass params in to Ability
# https://github.com/ryanb/cancan/issues/133
def 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
  end
end

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.rb
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? :hiring_manager
      can [:read, :update], Post, user_id: user.id
    end
  end
 end

#controllers/posts_controller.rb
class PostsController < ApplicationController::Base
  before_filter :authenticate_user

  def show
    @post = Post.find(params[:id])
    authorize! :read, @post # will thorow an exception if not allowed
  end
end 

Then, I just catch the exception on ApplicationController level.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!