Передача параметров в CanCan в RoR - PullRequest
8 голосов
/ 28 февраля 2012

У меня есть контроллер с методом, подобным;

def show

    if params[:format].eql?("pdf")
    // do something
    elsif params[:format].eql?("csv")
    // do something
    end
end

Но у меня есть пользователи с разными ролями.Поэтому я использую CanCan для управления контролем доступа.Теперь я хочу, чтобы роль X могла выполнять действие show в контроллере, если params[:format].eql?("csv")

Я думаю, что это может быть как; can :show, resource if params[:format].eql?("csv").Так как же я могу отправить параметры наility.rb?

Есть идеи?

Спасибо.

Ответы [ 3 ]

26 голосов
/ 28 февраля 2012

В ApplicationController добавьте следующее:

# CanCan - pass params in to Ability
# https://github.com/ryanb/cancan/issues/133
def current_ability
  @current_ability ||= Ability.new(current_user, params)
end
6 голосов
/ 06 мая 2012

Самый последний ответ в вики CanCan: https://github.com/ryanb/cancan/wiki/Accessing-Request-Data

1 голос
/ 28 февраля 2012

can принимает два аргумента: первый - это тип действия, которое пользователь пытается выполнить над ресурсом, второй - сам ресурс (может быть именем класса или переменной экземпляра). Если у вас правильно настроена Способность, вы сможете сделать что-то вроде этого:

def show
  if params[:format].eql?("pdf")
    // do something
  elsif params[:format].eql?("csv")
    if can? :read, resource
      #do stuff
    end
  end
end

Не забывайте, что вы должны пройти аутентификацию вашего пользователя перед выполнением любых проверок CanCan. can? метод возвращает только true или false. Мне обычно нравится использовать authorize! метод для проверки способностей. В отличие от can, возникает ошибка CanCan::AccessDenied, которую вы можете изящно спасти и обработать. Что-то в строках:

#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 

Затем я просто ловлю исключение на уровне ApplicationController.

...