0

我正在尝试创建类似product/:id/monthly/revenue/and的路径product/:id/monthly/items_sold以及等效的命名路线product_monthly_revenueand product_monthly_items_sold,这些路线只会显示图表。我试过了

resources :products do
    scope 'monthly' do
        match 'revenue', to: "charts#monthly_revenue", via: 'get'
        match 'items_sold', to: "charts#monthly_items_sold", via: 'get'
    end
end

但这给了我路线:

product_revenue    GET    /monthly/products/:product_id/revenue(.:format)    charts#monthly_revenue
product_items_sold GET    /monthly/products/:product_id/items_sold(.:format) charts#monthly_items_sold

wheremonthly被附加在前面,并且路由命名已关闭。我知道我可以这样做:

resources :products do
    match 'monthly/revenue', to: "charts#monthly_revenue", via: 'get', as: :monthly_revenue
    match 'monthly/items_sold', to: "charts#monthly_items_sold", via: 'get', as: :monthly_items_sold
end

但这不是 DRY,当我尝试添加更多类别(如每年)时,它会变得很疯狂。当我想将所有图表合并到一个控制器中时,使用命名空间会迫使我为每个命名空间创建一个新控制器。

所以我想总结的问题是:是否可以在没有命名空间控制器的情况下命名路由?或者是否可以合并命名路线类别的创建?

编辑:使用

resources :products do
  scope "monthly", as: :monthly, path: "monthly" do
    match 'revenue', to: "charts#monthly_revenue", via: 'get'
    match 'items_sold', to: "charts#monthly_items_sold", via: 'get'
  end
end

会给我路线

   monthly_product_revenue GET    /monthly/products/:product_id/revenue(.:format)    charts#monthly_revenue
monthly_product_items_sold GET    /monthly/products/:product_id/items_sold(.:format) charts#monthly_items_sold

这类似于第一个块,是出乎意料的,因为我希望如果一个范围嵌套在一个资源块中,那么只有范围块中的路由会受到范围的影响,而不是资源块。

编辑 2:之前忘记包含此信息,但我在 Rails 4.0.0 上,使用 Ruby 2.0.0-p247

4

2 回答 2

13

真正的解决方案是使用nested

resources :products do
  nested do
    scope 'monthly', as: :monthly do
      get 'revenue', to: 'charts#monthly_revenue'
      get 'items_sold', to: 'charts#monthly_items_sold'
    end
  end
end

参考:https ://github.com/rails/rails/issues/12626

于 2015-03-10T18:29:15.260 回答
1

以下是我可能会采取的方法:

periods = %w(monthly yearly)
period_sections = %w(revenue items_sold)

resources :products do
  periods.each do |period|
    period_sections.each do |section|
      get "#{period}/#{section}", to: "charts##{period}_#{section}", as: "#{period}_#{section}"
    end
  end
end

也可以使用命名路由并通过参数将值传递给控制器​​方法(确保在使用前正确验证):

resources :products do
  get ":period/:section", to: "charts#generate_report", as: :report
end

# report_path(period: 'monthly', section: 'revenue')
于 2013-10-24T03:44:19.467 回答