2010-09-04 10 views
20

Ho il seguente pezzo di codiceCome interrompere l'esecuzione di un controller di rotaie?

def show 
    unless logged_in? 
     login_required 
     return 
    end 
    #some additional code 
    #that should only execute 
    #if user is logged in 
end 

Questo funziona perfettamente. Ora vorrei spostare il controllo dell'accesso in un filtro precedente. Il problema è che, quando torno da un metodo esterno a show, non si ferma l'esecuzione di show ... come faccio a interrompere show di passare attraverso il codice da un metodo esterno (cioè uno che potrebbe essere chiamato da un filtro precedente)?

Grazie!

risposta

16

Se si restituisce un falso da un before_filter, l'esecuzione della richiesta verrà immediatamente interrotta.

Se il proprio metodo login_required restituisce falso (o reindirizzamento) se non è stato effettuato l'accesso e se restituisce true se lo sono, quindi solo before_filter :login_required, dovrebbe funzionare perfettamente.

Edit: Come Lenry afferma di seguito, questo non funzionerà in Rails 2.0.1+ Invece, per fermare l'uso di richiesta head :ok nel codice

+0

ha funzionato perfettamente. grazie! –

+0

Questo non è più valido. Controlla la risposta di Lenny qui sotto. – tdgs

17

in Rails versioni 2.0.1 e superiori, è necessario reindirizzare o inviare una risposta per interrompere l'esecuzione dell'azione.

Da Agile Web Development with Rails Errata:

# 45840: Quello che segue è corretto:.

"Se una prima del filtro restituisce false, l'elaborazione delle termina catena di filtri, e l'azione non è eseguire un filtro può visualizza anche le richieste di output o di reindirizzamento, nel qual caso l'azione originale non viene mai richiamata. "

Un before_filter non interrompe l'elaborazione della catena di filtri on on return false più.

Da note di rilascio di Rails 2.0.1: * Modificato before_filter arrestare per accadere automaticamente il rendering o reindirizzare, ma non è più il semplice ritorno falso [David Heinemeier Hansson]

--Rob Christie

redirect_to, render e head interromperanno l'esecuzione. Ad esempio, head :ok risponderà alla richiesta con solo il codice di risposta HTTP OK e l'azione non verrà eseguita.

+6

A meno che la chiamata 'render' sia all'interno di una catena di filtri, una chiamata a' render' * non * interromperà l'esecuzione dell'azione del controller. (http://guides.rubyonrails.org/layouts_and_rendering.html#avoiding-double-render-errors) – pje

+3

Se il rendering arresta l'esecuzione, perché si ottiene un doppio errore di rendering se si esegue il rendering due volte? – Mohamad

+4

L'importante distinzione qui è che i 3 metodi devono essere chiamati dal 'before_filter' per arrestare l'esecuzione. – maletor

1

per fermare la catena di richiamata in Rails 5 è possibile utilizzare

throw :abort 
+3

Non capisco dove sia il posto migliore, per "prendere" questo simbolo lanciato.Se voglio introdurre una logica comune a tutti i controller, ciò impedisce l'ulteriore elaborazione, e lancio ': abort' in' ApplicationController', dove lo prendo? – sameers

+0

thow: abort è solo per le convalide del modello e non per i controllori. – bkunzi01

Problemi correlati