2012-02-27 22 views
8

Ho un controller con un metodo simile;Passare parametri a CanCan in RoR

def show 

    if params[:format].eql?("pdf") 
    // do something 
    elsif params[:format].eql?("csv") 
    // do something 
    end 
end 

Ma ho utenti con ruoli diversi. Quindi uso CanCan per gestire il controllo degli accessi. Ora voglio che il ruolo X possa fare l'azione show nel controller iff params[:format].eql?("csv")

Penso che possa essere come; can :show, resource if params[:format].eql?("csv"). Quindi, come posso inviare parametri a ability.rb?

Qualche idea?

Grazie.

risposta

24

In ApplicationController aggiungere i seguenti:

# CanCan - pass params in to Ability 
# https://github.com/ryanb/cancan/issues/133 
def current_ability 
    @current_ability ||= Ability.new(current_user, params) 
end 
+0

Questo dovrebbe essere contrassegnato come la risposta. Grazie! –

+1

Perfetto - tranne rientrato di 4 spazi: D – Hendrik

1

can prende due argomenti: primo è tipo di azione che l'utente sta tentando di eseguire su una risorsa, secondo è risorsa (può essere nome di classe o variabile di istanza) stesso . Se avete la vostra abilità impostato correttamente, si dovrebbe essere in grado di fare qualcosa del genere:

def show 
    if params[:format].eql?("pdf") 
    // do something 
    elsif params[:format].eql?("csv") 
    if can? :read, resource 
     #do stuff 
    end 
    end 
end 

non dimenticare che bisogna avere il vostro utente autenticato prima di eseguire qualsiasi controllo Cancan. Il metodo can? restituisce true o false. Normalmente mi piace usare il metodo authorize! per controllare le abilità. A differenza di can, l'errore è CanCan::AccessDenied che è possibile salvare ed elaborare correttamente. Qualcosa nelle righe di:

#models/ability.rb 
class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new # guest user (not logged in) 

    if user.role? :admin 
     can :manage, :all 
    elsif user.role? :hiring_manager 
     can [:read, :update], Post, user_id: user.id 
    end 
    end 
end 

#controllers/posts_controller.rb 
class PostsController < ApplicationController::Base 
    before_filter :authenticate_user 

    def show 
    @post = Post.find(params[:id]) 
    authorize! :read, @post # will thorow an exception if not allowed 
    end 
end 

Quindi, ho appena rilevato l'eccezione sul livello ApplicationController.

+0

bellissimo esempio Simon ma non è quello che sto cercando. Perché uso semplicemente params [: format] per decidere il comportamento del metodo. Nel tuo esempio utilizzi i parametri per trovare un record. Il record passa alla capacità di decidere il controllo degli accessi. Ma non sto usando i parametri sulla tua strada. –