2012-03-21 4 views
7

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

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

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

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

+0

пропустил эту награду! :( – RGB

ответ

7

EDIT: пересмотренный для CanCanCan

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

Предыдущий ответ (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"] 

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

здесь модель макет для способности, с которой я работал с (стр)

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)]> 
] 
+0

Думаю, подведем итог, вам нужно будет собрать массив с содержимым по вашему выбору, сохранить его, а затем снова преобразовать его содержимое в строку, используя to_s! :) – RGB

+0

Это хак, который полагается на осуществление подробности. – tmandry

+0

Единственное, на что это опирается, это то, что пользователь использует жемчужину CanCan, что и использует OP. Классы способности и пользователя по своей сути доступны при использовании CanCan – RGB

5

Я хотел послать свои способности 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, которая реализует этот метод может():

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); 
    }); 
    } 
}); 
+0

Вы также можете использовать: subject => rule.instance_variable_get ("@ subject"). Map {| s | s.to_s}, как будто вы используете s.name, и ваш объект содержит символы, которые будут ошибочными – SteveA

Смежные вопросы