2010-12-28 11 views
2

Aufträge können viele Zustände haben. Ich möchte für diese Namen Routen erstellen. Ich brauche den Status als Parameter an den Controller. Hier ist, was ich dachte, aber es funktioniert offensichtlich nicht.Routing-Variablen für Schienen

match "order/:state/:id" => "orders#%{state}", as: "%{state}" 

So würde ich Auftrag/Adresse/17 auf dem Weg zu Aufträgen # Adresse mag, mit: Staat und: id als params übergeben werden. Gleichermaßen würde Bestellung/Versand/17 zu Bestellungen # Versand, wieder: Zustand und: ID würde übergeben werden.

Hier ist der Controller.

class OrdersController < ApplicationController 

    before_filter :load_order, only: [:address, :shipping, :confirmation, :receipt] 
    before_filter :validate_state, only: [:address, :shipping, :confirmation, :receipt] 


    def address 
    @order.build_billing_address unless @order.billing_address 
    @order.build_shipping_address unless @order.shipping_address 
    end 


    def shipping 
    @shipping_rates = @order.calculate_shipping_rates 
    end 


    def confirmation 

    end 


    def receipt 

    end 

    private 

    def load_order 
    @order = Order.find(params[:id]) 
    end 

    # Check to see if the user is on the correct action 
    def validate_state 
    if params[:state] 
     unless params[:state] == @order.state 
     redirect_to eval("#{@order.state}_path(:#{@order.state},#{@order.id})") 
     return 
     end 
    end 
    end 

end 

Hier ist, was wir am Ende mit gehen:

routes.rb

%w(address shipping confirmation receipt).each do |state| 
    match "order/#{state}/:id", :to => "orders##{state}", :as => state, :state => state 
end 

orders_controller.rb

def validate_state 
    if params[:state] 
     unless params[:state] == @order.state 
     redirect_to(eval("#{@order.state}_path(@order)")) 
     return 
     end 
    end 
    end 
+0

Wenn Ihre URL ist '/ Auftrag/Adresse/17', wobei Zustandsinformationen aus genommen wird: Das wird Sie params[:state], auch erhalten lassen? Wenn das nicht url gemeint ist, was ist das? –

+0

Ich habe es gerade bearbeitet, um ein bisschen mehr von dem zu zeigen, was ich mache. –

Antwort

6

Sie geht nicht auf in der Lage sein, d zu erstellen named benannte Routen mit dieser Art von Syntax, aber Sie verwenden im Grunde nur :state als :action. Wenn Sie :state durch :action ersetzen und den Controller manuell angeben, funktioniert es. Offensichtlich müssen Sie Ihren Code ändern, um params[:action] statt params[:state] (oder ordnen Sie diese Variable in einem before_filter), aber darüber hinaus sollte es gut funktionieren.

match "order/:action/:id", :controller => "orders" 

Wären Sie sich bewusst, dass, wenn Aufträge RESTful Ressourcenzuordnungen wie create oder delete haben, diese Route GET-Anfragen sie erlauben würde, das wäre schlecht; Sie können nur explizite Routen für jede Aktion hinzufügen, die Sie abschließen möchten.

%w(address shipping).each do |state| 
    match "order/#{state}/:id", :to => "orders##{state}", :as => state, :state => state 
end 
+0

Dies ist eine großartige Antwort. Vielen Dank für diesen zweiten Teil, der einen großen Unterschied in der Art und Weise, wie wir ihn umgesetzt haben, gemacht hat. –