如何在 rails 中拥有一个带动作的命名空间?

How to have a namespace with action in rails?

下面我给出了routes.rb的代码:

  resources :analytics

  namespace :analytics do
    resources :users, only: [:show, :index]
  end

在这里,我在 controllers 文件夹中有一个 analytics_controller.rb,在 Controllers 文件夹中有一个 Analytics 文件夹,其中包含此 users_controller.rb

所以每当我想去 http://localhost:3005/analytics/users 访问 users_controller 的索引时,它只会将我发送到 analytics_controller 的显示操作,因为它需要 [=21] =] 作为上面的 :id url.

我该怎么办?我想同时保留 analytics_controller 的所有操作以及 users_controller.

的所有操作

如果您希望路由器首先匹配 analytics/users 路径,您需要将命名空间放在资源之前:

namespace :analytics do
  resources :users, only: [:show, :index]
end
resources :analytics

请检查将要生成的路由

localhost:3000/rails/info/routes

那么必须是 users_controller 必须是 controller/analytics/users_controller.rb

里面的命名空间
class Analytics::UsersControllers < ApplicationController
end

UserController 操作的路径应该是

analytics_users_path & analytics_users_path(user_id)

路由按照它们定义的顺序具有优先级。因此,如果您希望 /analytics/users 由 users#index 处理,您需要先定义该路由。

namespace :analytics do
  get 'users', to: "users#index"
end

resources :analytics

您似乎也不了解 nested routes 的工作原理。使用资源来定义嵌套路由会将 analytics/:analytic_id/users 作为索引。

resources :analytics, only: [] do
  resources :users, only: [:index]
 end

        Prefix Verb URI Pattern                             Controller#Action
analytic_users GET  /analytics/:analytic_id/users(.:format) users#index

但这并不是一种非常 restful 的方式来设置路线。我会建议:

Rails.application.routes.draw do

  namespace :users do
    get :analytics, to: 'analytics#all'
  end

  resources :users, only: [] do
    resources :analytics, module: :users, only: [:index]
  end
end

这将给出以下路线:

         Prefix Verb URI Pattern                         Controller#Action
users_analytics GET  /users/analytics(.:format)          users/analytics#all
 user_analytics GET  /users/:user_id/analytics(.:format) users/analytics#index

这里的主要区别在于路由清楚地表明所表示的资源是属于用户或集合的分析。

使用 module 选项将 "nested" 路由发送到 Users::AnalyticsController,这是区分不同上下文的好方法。

class Users::AnalyticsController
  # Display all analytics for all users
  # GET /users/analytics
  def all
    @users = User.all
    @analytics = Analytic.where(user: @users)
  end

  # Display all analytics for a user
  # GET /users/:user_id/analytics
  def index
    @user = User.includes(:analytics).find(params[:user_id])
    @analytics = @user.analytics
  end
end