Rails Can Can Ability Class для нескольких моделей Devise

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

Я использую Active Admin, Can Can и Devise, и я успешно создал модели User и AdminUser.

У меня это в умении. Rb

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new

    if (user)
      can :manage, Item
    end
  end
end

Теперь я использовал эту вики-запись, чтобы определить, что мы действительно можем определить собственный файл способностей и использовать его вместо способности .rb:

https://github.com/ryanb/cancan/wiki/changing-defaults

Но то, что я хотел сделать, это иметь возможность использоватьility.rb, если "пользователь без прав администратора" вошел в систему, и настраиваемую возможность, если пользователь-администратор вошел в систему.

Дополнительный вопрос: можно ли сделать так, чтобы мне не требовалось настраиваемое, и я мог бы установить разрешения в одном файле capacity.rb?


person yretuta    schedule 26.10.2011    source источник
comment
Ах ты прав. Я не заметил, что вы использовали отдельный класс для User и AdminUser. Вы должны иметь возможность изменить класс, используемый Active Admin, но не будучи пользователем этой системы, я не уверен, где именно он находится. Возможно, стоит проверить свои инициализаторы.   -  person jdl    schedule 26.10.2011


Ответы (1)


Я никогда не использовал ActiveAdmin, поэтому я не совсем уверен, что я что-то упускаю, но не похоже, что эта структура полагается на CanCan. Вот почему я предполагаю, что вы определяете метод current_ability, как описано в вики, и его экземпляр создается с помощью Ability.new(current_user).

Если это так, и ваш current_user может быть либо User, либо AdminUser, тогда нет проблем с проверкой этого в классе Ability:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new

    if user.kind_of? AdminUser
      can :manage, Item
    elsif user.kind_of? User
      can :read, Item
    end
  end
end

Вы можете просто взглянуть на тип пользователя и соответствующим образом изменить правила. Вы также можете использовать is_a? вместо kind_of? для более строгой проверки, но это, вероятно, не требуется и может вызвать проблемы, если вы решите выполнить наследование позже.

Другой способ проверить - определить метод admin? в обеих моделях. Это может быть лучший способ сделать это, поскольку явная проверка типов не очень популярна в Ruby - она ​​часто ограничивает ваш выбор. Это могло бы выглядеть так:

class User < ActiveRecord::Base
  def admin?
    false
  end
end

class AdminUser < ActiveRecord::Base
  def admin?
    true
  end
end

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new

    if user.admin?
      can :manage, Item
    else
      can :read, Item
    end
  end
end
person Andrew Radev    schedule 27.10.2011