Rails - 如何针对嵌套资源路由定位嵌套控制器

Mar*_*ejo 5 routes ruby-on-rails

在我的routes.rb我有

namespace :admin do
  resources :clients do, only: [:index] do
    resources :products, only: [:index, :new, :create]
  end

  resources :products, only: [:index]
end
Run Code Online (Sandbox Code Playgroud)

请注意,我有两行resources :products. 一个嵌套在 中resources :clients,另一个作为 上的顶级资源:admin;这两者在应用程序中都有不同的目的。

rake routes给我:

           admin_clients GET  /admin/clients(.:format)                         admin/clients#index
   admin_client_products GET  /admin/clients/:client_id/products(.:format)     admin/products#index
                         POST /admin/clients/:client_id/products(.:format)     admin/products#create
new_admin_client_product GET  /admin/clients/:client_id/products/new(.:format) admin/products#new
          admin_products GET  /admin/products(.:format)                        admin/products#index                    
Run Code Online (Sandbox Code Playgroud)

我有一个admin_client_products嵌套product#index资源。我也有admin_products顶级product#index资源。然而,它们指向相同的控制器操作:admin/product#index

问题:此时,我需要 Rails 来推断这是两个不同的操作。使用rails约定,有没有办法告诉rails这两个资源应该有不同的控制器操作,即一个应该命中,admin/products#index另一个应该命中admin/clients/products#index

嵌套路由应该这样:

class Admin::Clients::ProductsController < Admin::BaseController      
  def index; end
end
Run Code Online (Sandbox Code Playgroud)

顶级路线应该这样:

class Admin::ProductsController < Admin::BaseController      
  def index; end
end
Run Code Online (Sandbox Code Playgroud)

Was*_*ain 3

绝对可以!

在这里,您需要通过显式指定用于资源的控制器来自定义资源路由。该:controller选项将让您做到这一点。

clients/products因此,在您的情况下,指定资源的控制器admin_clients_products将以您想要的方式工作。

namespace :admin do
  resources :clients, only: [:index] do
    resources :products, only: [:index, :new, :create], controller: 'clients/products'
  end                                                 # ------------------------------

  resources :products, only: [:index]
end
Run Code Online (Sandbox Code Playgroud)

rails routes现在会给你你想要的:

admin_client_products    GET /admin/clients/:client_id/products(.:format)   admin/clients/products#index
                         POST   /admin/clients/:client_id/products(.:format)     admin/clients/products#create
new_admin_client_product GET    /admin/clients/:client_id/products/new(.:format) admin/clients/products#new
admin_clients            GET    /admin/clients(.:format)                         admin/clients#index
admin_products           GET    /admin/products(.:format)                        admin/products#index
Run Code Online (Sandbox Code Playgroud)

=========================

额外位:

如果您想省略/adminurl 中的部分(我的意思是,如果您的应用程序的路由设计允许),那么您可以使用:

范围模块:'admin'做...结束
像下面这样:

scope module: 'admin' do...end

突然之间,你的路线就会开始看起来棒极了:)

scope module: 'admin' do
  resources :clients, only: [:index] do
    resources :products, only: [:index, :new, :create], controller: 'clients/products'
  end

  resources :products, only: [:index]
end
Run Code Online (Sandbox Code Playgroud)