2011-08-18 6 views
7

Quiero usar CanCan para manejar mis permisos. Mi sitio tiene muchos niveles de permisos diferentes, y la mayoría de ellos tiene en cuenta el contexto. Por ejemplo, aquí están las relaciones en mis 3 modelos principales:Autorización de contexto con el uso de CanCan

class User < ActiveRecord::Base 
    has_many :league_relations 
    has_many :leagues, :through => :league_relations 
end 

class League < ActiveRecord::Base 
    has_many :league_relations 
    has_many :users, :through => :league_relations 
end 

class LeagueRelation < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :league 
end 

Nota, LeagueRelations es un recurso anidado de ligas. Lo que quiero hacer es permitir que un usuario modifique las ligas y medir la autorización de cada usuario a partir de los datos almacenados en league_relation. Entonces me gustaría que un usuario modifique la relación de liga, basándose solo en los datos almacenados en el modelo de usuario.

Para ser sucinto: básicamente quiero que LeagueRelations se use para autorizar acciones de la Liga y que los Usuarios se usen para autorizar acciones de LeagueRelations. es decir, league_relation.owner = true para eliminar una liga, pero propietario.usuario? debe ser verdadero para eliminar una LeagueRelation. ¿Cómo puedo autorizar según los atributos de league_relation cuando está dentro del controlador de la liga y autorizo ​​otras acciones en otros controladores en otros modelos? Por favor, deje un comentario si necesita más aclaraciones.

Gracias.

Respuesta

10

Ok, he resuelto el problema. Mi caso de uso se menciona brevemente al comienzo de CanCan README y me lo perdí. Puede definir nuevas clases de Habilidad en la aplicación/modelos/que toman un parámetro diferente a current_user. Para ello, se pone el siguiente en el controlador:

def current_ability 
    if params[:controller] == 'leagues' 
    @current_ability = LeagueAbility.new(current_user_league_relation) 
    elsif params[:controller] == 'league_relations' 
    @current_ability = LeagueRelationAbility.new(current_user_league_relation) 
    else 
    @current_ability = Ability.new(current_user) 
    end 
end 

Ahora puede crear league_ability.rb en app/models /.

class LeagueAbility 
    include CanCan::Ability 

    def initialize(league_relation) 
    league_relation ||= LeagueRelation.new 

    if league_relation.owner? 
     can :manage, League, :id => league_relation.league_id 
    elsif league_relation.moderator? 
     can :manage, League, :id => league_relation.league_id 
     cannot [:delete, :destroy], League 
    else 
     can :read, League 
     can :create, League 
    end  
    end 
end 

Una cosa a tener en cuenta es que esto depende de que el controlador de la aplicación invoque un método en una clase secundaria. ¡Espero que ayude!

Cuestiones relacionadas