Wie kann ich die Reihenfolge angeben, in der before_filters ausgeführt werden?

68

Gibt Rails eine Garantie für die Reihenfolge, in der Filter mit einer der folgenden Verwendungen ausgeführt werden:

before_filter [:fn1, :fn2]

oder

before_filter :fn1
before_filter :fn2

Ich würde mich über jede Hilfe freuen.

James
quelle

Antworten:

87

Wenn Sie auf http://api.rubyonrails.org/v2.3.8/classes/ActionController/Filters/ClassMethods.html verweisen , gibt es eine Unterüberschrift mit dem Namen "Filterkettenreihenfolge". Hier ist der Beispielcode daraus:

class ShoppingController < ActionController::Base
    before_filter :verify_open_shop

class CheckoutController < ShoppingController
    prepend_before_filter :ensure_items_in_cart, :ensure_items_in_stock

Nach der Erklärung:

Die Filterkette für die CheckoutControllerist jetzt :ensure_items_in_cart, :ensure_items_in_stock, :verify_open_shop.

Sie können also die Reihenfolge der Filterkette explizit so angeben.

Johnny Woo
quelle
Genau das, wonach ich gesucht habe. @Johnny Du bist ein Leben sicherer. Ich danke dir sehr.
Surya
@Sector und JohnnyWoo: Ihre Links zu rails.rubyonrails.org/classes/ActionController/Filters/… sind tot.
Kevin
1
Auf Schienen 3.2.14 ist die Filterkette, die ich bekomme, die folgende :: sure_items_in_stock ,: sure_items_in_cart ,: verify_open_shop
Raf
1
Ein Befehl zum Ausgeben und Debuggen der genauen Filterkette wäre hilfreich.
Epigene
25

Vor_Filter Bestellung in Schienen http://b2.broom9.com/?p=806

Bestellung der Filterkette http://rails.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html

Wenn Sie eine Garantiebestellung benötigen, können Sie dies tun:

before_filter :fn3

def fn3
  fn1
  fn2
end
Sektor
quelle
3
Wird das nicht zu Problemen führen, wenn beide fehlschlagen und versuchen, umzuleiten?
Groxx
Sie können verwenden, wenn in fn3 mit Check Return Ergebnis von fn1, fn2
Sektor
Wenn fn1 fehlschlägt (dh false zurückgibt) und fn2 nicht ausführen muss, müssen Sie etwas mehr Logik hinzufügen. So etwas wie:fn1 ? fn2 : false
Eric H.
3

Soweit ich das beurteilen kann, setzen Sie die erste Funktion, die Sie ausführen möchten, und so weiter.

Also so etwas wie:

before_filter :fn1, :fn2

def fn1
  puts 'foo'
end

def fn2
  puts 'bar'
end

Würde ausführen fn1, dann fn2.

Hoffentlich hilft das.

Christian Fazzini
quelle
Ich benutze Rails 4 und selbst wenn meine Bestellung lautet :fn1, :fn2: fn2 wird zuerst aufgerufen.
r3b00t
1

Die Filterkette für CheckoutControllerfolgt nicht dieser Reihenfolge

:ensure_items_in_cart, :ensure_items_in_stock, :verify_open_shop

Stattdessen sollte es sein

:ensure_items_in_stock, :ensure_items_in_cart, :verify_open_shop
HEraju
quelle