Rails Can Can Класс Способности Для Многократных Разработанных Моделей - PullRequest
10 голосов
/ 26 октября 2011

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

Я использую 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

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

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

1 Ответ

12 голосов
/ 27 октября 2011

Я никогда не использовал 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
...