2010-12-28 2 views
2

Les commandes peuvent avoir plusieurs états. Je voudrais créer des itinéraires nommés pour ceux-ci. J'ai besoin que l'état soit transmis au contrôleur en tant que param. Voici ce que je pensais, mais ça ne marche évidemment pas.Rails Variables de routage

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

Je voudrais donc commande/adresse/17 pour acheminer des ordres # adresse, avec: état et: id être transmis comme params. De même, order/shipping/17 acheminerait aux commandes # shipping, encore une fois: state et: id seraient passés.

Voici le contrôleur.

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 

Voici ce que nous avons fini par aller avec:

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

Si votre URL est '/ commande/adresse/17', où les informations d'état est tiré? Si ce n'est pas une URL, qu'est-ce que c'est? –

+0

Je viens de l'éditer pour montrer un peu plus de ce que je fais. –

Répondre

6

Vous n'êtes pas allez être capable de créer d ynamic routes nommées avec ce genre de syntaxe, mais vous utilisez simplement :state comme :action. Si vous remplacez :state par :action et spécifiez le contrôleur manuellement, cela fonctionnera. Évidemment, vous devrez changer votre code pour regarder params[:action] plutôt que params[:state] (ou mapper cette variable dans un before_filter), mais au-delà cela devrait fonctionner correctement.

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

Sachez que si les commandes a mappings des ressources RESTful comme create ou delete, cette voie permettrait des requêtes GET à eux, ce qui serait mauvais; vous pouvez simplement ajouter des routes explicites pour chaque action que vous voulez effectuer. Cela vous permettra de vous params[:state], ainsi:

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

C'est une bonne réponse. Merci pour cette deuxième partie, a fait une énorme différence dans la façon dont nous l'avons mis en œuvre. –