2013-09-03 15 views
19

In che ordine si verificano i filtri? In particolare, in quale ordine avvengono i filtri before_action, in relazione all'ereditarietà? Ad esempio, funziona:In che ordine si verificano i filtri?

class A < ActionController::Base 
    before_action :set_user 

    def set_user 
    @user = something 
    end 
end 

class B < A 
    before_action :set_post 

    def show 
    render @post 
    end 

    def set_post 
    @post = @user.posts.first 
    end 
end 

"B # show" funziona? Quali sono le regole per l'ordine del filtro per riferimento futuro? Non riesco a trovare nulla di tutto ciò nella documentazione di Rails.

+0

Non ha la classe '' 'A''' ereditata da qualche controller come * ActionController *? Se viene eseguita un'azione su istanza di '' B''', i filtri ereditati come '' 'set_user''' vengono chiamati per primi. –

+0

Mi dispiace per quello. Aggiustato. –

+0

come risolvere l'ordine: http://stackoverflow.com/questions/5711797/how-can-i-specify-the-order-that-before-filters-are-executed –

risposta

19

vi suggerisco di dare un'occhiata a the source code e API Docs sui filtri.

L'ordinamento di default dovrebbe essere

  1. :set_post
  2. :set_user

Penso che se si voleva spingere :set_user in cima alla pila si potrebbe modificare la riga in A a

prepend_before_action :set_user 

Vale anche la pena sottolineare che questa non è l'unica domanda sull'argomento; ci sono others here on SO.


Per quanto riguarda la situazione specifica, sembra che sarà necessario cambiare A come ho detto sopra, al fine di avere @user essere assegnato per il momento set_post in B piste.


A partire dal 4.2.6 (probabilmente modificato in una versione precedente), l'ordinamento è ora genitore prima di bambino:

  1. :set_user
  2. :set_post
+1

Grazie. Questo è quello di cui avevo bisogno. –

+0

Hai l'ordine predefinito (sopra) all'indietro. I before_filters sulla classe derivata (B) vengono chiamati prima della classe base (A) before_filters. Così è: 1.: set_user e 2.: set_post Nota inoltre, after_filters vengono chiamati in ordine inverso, il più derivato prima. –

+6

Ho appena provato questo su Rails 4.2 e sembra che questo non è più valido. La callback della classe padre viene eseguita per prima e quindi la callback della classe child. Quindi: 1) 'set_user', 2)' set_post' – head

0

Sì, il codice funzionerà come previsto.

I before_filters sulla classe derivata (B) vengono chiamati prima dei before_filters sulla classe base (A). Quindi l'ordine dei metodi chiamati sono:

  1. set_user()
  2. set_post()
  3. spettacolo()

Si noti inoltre, after_filters sono chiamati in ordine inverso, la più derivata prima .

+2

Come hai detto, il before_filter nella classe derivata viene chiamato per primo, poiché B è la classe derivata, set_post verrà chiamato prima e quindi set_user. – DallaRosa

5

La risposta accettata non è più valida a partire da Rails 4.2.6. Probabilmente è stato modificato in precedenza, ma questa è la versione in cui mi trovo adesso.

filtri controllanti sono ora chiamati prima di filtri bambino, quindi l'ordinamento saranno ora:

  1. :set_user
  2. :set_post

E, se ci pensate, che l'ordinazione in realtà ha più senso. Come precedentemente detto, se hai bisogno che il bambino chiami il filtro prima del genitore, devi usare prepend_before_action.

Problemi correlati