如何在 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
下面我给出了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