2012-03-21 7 views
7

que quiere almacenar una vista Post, pero la vista depende de los permisos del usuario actual (por ejemplo, sólo muestro el enlace "editar" si current_user.can?(:edit, @post))Obtener una cadena que representa las habilidades de cancán de un usuario

Así Quisiera que mi clave de caché incluyera una representación de las capacidades de CanCan del usuario actual, para poder invalidar el caché cuando cambien las habilidades del usuario

SO: ¿cómo puedo obtener una cadena que represente las habilidades del usuario actual de modo que 2 usuarios diferentes con las mismas capacidades generarán la misma "cadena de habilidad"?

He intentado user.ability.inspect, pero esto no produce la misma cadena para diferentes usuarios que tienen las mismas habilidades

+0

perdidas que recompensa! :( – RGB

Respuesta

7

EDIT: revisado para CanCanCan

partir de la versión 1.12 de CanCanCan (la continuación de la comunidad de CanCan), Ability.new(user).permissions devuelve un hash con todos los permisos para el usuario dado.

respuesta

anterior (CanCan):

Esto podría ser un poco compleja ... pero aquí va ..

Si pasa el usuario especificado en el modelo de habilidad requerido por CanCan, se puede acceder a la definición de ese papel usuarios utilizando instance_variable_get, y luego dividirlo en cualquiera de los valores cadena que desea desde allí ..

>> 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"] 

si desea conocer los modelos en los que esas reglas se encuentran en flicted sobre, puede acceder a la variable de instancia @subjects para obtener su nombre ..

Este es el diagrama modelo para la capacidad de la que trabajé con (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)]> 
] 
+0

Supongo que para resumir, tendrías que construir la matriz con el contenido que elijas, guardarla y luego convertir sus contenidos en la cadena usando to_s nuevamente :) :) – RGB

+0

Este es un truco que depende de detalles de implementacion. – tmandry

+0

Lo único en lo que esto se basa es en que el usuario está utilizando la gema CanCan, que es lo que usa el OP. Las clases de Capacidad y Usuario están inherentemente disponibles cuando se usa CanCan – RGB

5

quería enviar mis habilidades para JS, y para dar seguimiento a esta publicación, aquí está mi método de ayuda que puedes usar para convertir tus habilidades de usuario a una matriz en tu controlador. Luego llamo .to_json en la matriz y la paso a 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 

Y aquí es mi modelo Backbone.js que implementa el método de lata():

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

También puede usar simplemente: subject => rule.instance_variable_get ("@ subject"). Map {| s | s.to_s}, como si usara s.name y su tema contiene símbolos, generará un error – SteveA

Cuestiones relacionadas