Использование CanCan для авторизации ресурса на основе ассоциации «многие ко многим».

У меня есть две модели, события и пользователи, которые имеют ассоциацию «многие ко многим». Пользователь может быть администратором, менеджером или продюсером. Только производитель, который принадлежит к событию, должен иметь возможность прочитать это событие. Я пытался применить это ограничение к модели способностей, но это не помогло, и каждый производитель может читать все события. Что я делаю неправильно?

class Event < ActiveRecord::Base
 has_and_belongs_to_many :producers, :class_name => "User", :join_table => "events_producers"
end


class CreateEventUserJoinTable < ActiveRecord::Migration
  def self.up
    create_table :events_producers, :id => false do |t|
      t.integer :event_id
      t.integer :user_id
    end
  end

  def self.down
    drop_table :events_producers
  end
end

class Ability
  include CanCan::Ability
  def initialize(user)
    user ||= User.new() # Guest user
    if user.role? :manager
      can :manage, :all
    elsif user.role? :admin
      can :read, Event
      can :update, Event
      can :create, Event
    elsif user.role? :producer
      can :read, Event do |event|
          event.try(:producers).include?(user)
        end
    end
  end
end

person Cirdes    schedule 05.05.2011    source источник


Ответы (2)


Проблема в том, что условия в блоке способностей не используются, когда это вызов на основе класса, например. индексные действия. См. https://github.com/ryanb/cancan/wiki/Defining-Abilities-with-Blocks для уточнения.

Для индексных действий необходимо определить ограничения вне блока.

person Sean Coleman    schedule 31.08.2011

Немного устарел ваш вопрос, но без использования блока вы можете определить вышеуказанное условие следующим образом:

can :read, Event, :producers => {:user_id => user.id}

Кроме того, с этой строкой не нужно спрашивать, есть ли у пользователя роль производителя.

person Skully    schedule 16.11.2012