Rails Routing Variables - PullRequest
       3

Rails Routing Variables

2 голосов
/ 28 декабря 2010

Заказы могут иметь много состояний. Я хотел бы создать именованные маршруты для тех. Мне нужно, чтобы состояние передавалось контроллеру в качестве параметра. Вот о чем я думал, но это, очевидно, не работает.

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

Так что я бы хотел, чтобы order / address / 17 направлялся на адреса order # с параметрами: state и: id, передаваемыми в качестве параметров. Аналогично, order / shipping / 17 будет перенаправлять на заказы # shipping, снова: state и: id будет передан.

Вот контроллер.

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

Вот то, к чему мы пришли:

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

1 Ответ

7 голосов
/ 28 декабря 2010

Вы не сможете создавать динамические именованные маршруты с таким синтаксисом, но вы просто используете :state в качестве :action. Если вы замените :state на :action и укажете контроллер вручную, он будет работать. Очевидно, вам придется изменить свой код так, чтобы он смотрел на params[:action], а не params[:state] (или отображал эту переменную в before_filter), но помимо этого он должен работать нормально.

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

Имейте в виду, что если у заказов есть сопоставления ресурсов RESTful, такие как create или delete, этот маршрут разрешит GET-запросы к ним, что было бы плохо; Вы можете просто добавить явные маршруты для каждого действия, которое вы хотите выполнить. Это также позволит вам получить params[:state]:

%w(address shipping).each do |state|
  match "order/#{state}/:id", :to => "orders##{state}", :as => state, :state => state
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...