Получить строку, которая представляет способности CanCan пользователя - PullRequest
9 голосов
/ 21 марта 2012

Я хочу кэшировать представление Post, но представление зависит от разрешений текущего пользователя (например, я показываю ссылку «редактировать» только если current_user.can?(:edit, @post))

Так что я бы хотел, чтобы мой ключ кеша включал представление способностей текущего пользователя CanCan, чтобы я мог сделать недействительным кеш при изменении способностей пользователя

ТАК: как я могу получить строку, которая представляет способности текущего пользователя, чтобы 2 разных пользователя с одинаковыми способностями генерировали одну и ту же "строку способностей"?

Я пробовал user.ability.inspect, но это не выдает одну и ту же строку для разных пользователей, имеющих одинаковые способности

Ответы [ 2 ]

9 голосов
/ 13 апреля 2012

РЕДАКТИРОВАТЬ: исправлено для CanCanCan

Начиная с версии 1.12 CanCanCan (продолжение сообщества CanCan), Ability.new(user).permissions возвращает хэш со всеми разрешениями для данного пользователя.

Предыдущий ответ (CanCan):

Это может быть немного сложно ... но здесь все идет ..

Если вы передадите указанного пользователя вмодель способностей, требуемую CanCan, вы можете получить доступ к определению роли этого пользователя с помощью instance_variable_get, а затем разбить его на любые строковые значения, которые вам нужны.

>> u=User.new(:role=>"admin")
>> a=Ability.new(u)
>> a.instance_variable_get("@rules").collect{ 
      |rule| rule.instance_variable_get("@actions").to_s
   }
=> ["read", "manage", "update"]

, если вы хотите узнать моделив котором применяются эти правила, вы можете получить доступ к переменной экземпляра @subjects, чтобы получить ее имя.

вот макет модели для Ability, с которой я работал (pp)

Ability:0x5b41dba @rules=[
  #<CanCan::Rule:0xc114739 
    @actions=[:read], 
    @base_behavior=true, 
    @conditions={}, 
    @match_all=false, 
    @block=nil, 
    @subjects=[
      User(role: string)]>, 
  #<CanCan::Rule:0x7ec40b92 
    @actions=[:manage], 
    @base_behavior=true, 
    @conditions={}, 
    @match_all=false, 
    @block=nil, 
    @subjects=[
      Encounter(id: integer)]>, 
  #<CanCan::Rule:0x55bf110c 
    @actions=[:update], 
    @base_behavior=true, 
    @conditions={:id=>4}, 
    @match_all=false, 
    @block=nil, 
    @subjects=[
      User(role: string)]>
]
7 голосов
/ 29 января 2013

Я хотел отправить свои способности в JS, и в продолжение этого поста, вот мой вспомогательный метод, который вы можете использовать для преобразования ваших пользовательских способностей в массив вашего контроллера.Затем я вызываю .to_json для массива и передаю его в javascript.

def ability_to_array(a)
  a.instance_variable_get("@rules").collect{ |rule| 
  { 
    :subject => rule.instance_variable_get("@subjects").map { |s| s.name }, 
    :actions => rule.instance_variable_get("@actions").map { |a| a.to_s }
  }
}
end

И вот моя модель Backbone.js, которая реализует метод can ():

var Abilities = Backbone.Model.extend({
  can : function(action, subject)
  {
    return _.some(this.get("abilities"), function(a) {
      if(_.contains(a["actions"], "manage") && _.contains(a["subject"], "all")) return true;
      return _.contains(a["actions"], action) && _.contains(a["subject"], subject);
    });
   }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...