2015-06-15 18 views
8

Vorrei sapere come funziona il load_and_authorize_resource all'interno. Ho cercato la pagina github Link e ho provato a capire, ma non ho trovato nulla di utile. Capisco solo che load_and_authorize_resource è come un before_filter e carica (in qualche modo) l'abilità che abbiamo scritto in ability.rbCanCan spiegazione di load_and_authorize_resource

Vorrei sapere come è possibile. Voglio dire, non voglio studiare TUTTA la gemma, ma voglio solo vedere come può caricare la capacità di una risorsa in un controller e se lo load_and_authorize_resource è davvero una sorta di before_filter.

risposta

11

disclaimer: per motivi di semplicità, tralascio intenzionalmente alcune chiamate a brevi metodi interni. L'intera catena di chiamata può essere ottenuta seguendo la definizione del metodo load_and_authorize_resource e così via.

Come indicato nella documentazione, load_and_authorize_resource istituisce un before_filter ...

# cancan/lib/cancan/controller_additions.rb 
def load_and_authorize_resource(*args) 
    cancan_resource_class.add_before_filter(self, :load_and_authorize_resource, *args) 
end 

... che richiede due metodi: load_resource e authorize_resource.

# cancan/lib/cancan/controller_resource.rb 
def load_and_authorize_resource 
    load_resource 
    authorize_resource 
end 

Per avere un'idea del loro comportamento, esamineremo entrambi con attenzione.

Sulla base params hash che è stata approvata alla vostra azione di controllo, load_resource fa una decisione se si deve ottenere una nuova istanza di una classe (ad esempio Post.new) o find una particolare istanza sulla base di params[:id] (per esempio Post.find(params[:id])). Tale istanza (o una raccolta di istanze per azioni come index) viene assegnata alla corrispondente variabile di istanza dell'azione del controllore.

# cancan/lib/cancan/controller_resource.rb 
def load_resource 
    unless skip?(:load) 
    if load_instance? 
     # here you have obtained your object, e.g. Post with id=5 
     # and placed it into cancan resource_instance variable. 
     # it has automatically set up @post instance variable for you 
     # in your action 
     self.resource_instance ||= load_resource_instance 
    elsif load_collection? 
     self.collection_instance ||= load_collection 
    end 
    end 
end 

Più tardi, authorize_resource viene chiamato. La sintassi delle logiche interne dovrebbe essere familiare a voi: controllare le abilità con le mani sembra proprio la stessa cosa succede all'interno di questo metodo. Fondamentalmente si prende uno resource_instance ottenuto al passaggio precedente, params[:action] che è il nome di un'azione corrente e si verifica se è possibile accedere a un'azione specifica per determinati oggetti.

# cancan/lib/cancan/controller_resource.rb 
def authorize_resource 
    unless skip?(:authorize) 
    # similar to what happens when you call authorize!(:show, @post) 
    @controller.authorize!(authorization_action, resource_instance || resource_class_with_parent) 
    end 
end 

Finché sollevare eccezioni all'interno di before_filter ferma azione di controllo venga eseguito, non riuscendo a passare l'autorizzazione qui ottiene reindirizzato a url casa della vostra applicazione, illustrata 500 pagina di errore o qualunque comportamento definito per CanCan::AccessDenied movimentazione.

D'altra parte, nel caso in cui abbiate passato con successo l'autorizzazione, il vostro codice d'azione viene eseguito. Ora hai accesso alla variabile di istanza (ad esempio @post) che è stata impostata da CanCan al passaggio load_resource.

+0

grazie! mi aiuti molto! – Vito

+1

Come fa a sapere se recuperare una raccolta o creare o caricare un'istanza? – mwfearnley