Rails 3路由 - 从命名空间中指定精确的控制器

时间:2011-04-11 00:25:42

标签: ruby-on-rails ruby-on-rails-3 routing

我遇到过一些我之前没遇到的路由命名空间问题。这实际上是我正在做的一些宝石开发的一部分 - 但我已经重新设计了这个问题以适应更通用的rails情况。

基本上,我有一个命名空间路由,但我希望它指向一个通用(顶级)控制器。

我的控制器是PublishController,它处理许多不同类型的模型的发布 - 它们都符合相同的接口,但可以在不同的名称空间下。我的路线看起来像这样:

# config/routes.rb

namespace :manage do
  resources :projects do
    get 'publish' => 'publish#create'
    get 'unpublish' => 'publish#destroy'
  end
end

问题是这会产生以下路线:

manage_project_publish GET    /manage/projects/:project_id/publish(.:format)        {:controller=>"manage/publish", :action=>"create"}
manage_project_unpublish GET    /manage/projects/:project_id/unpublish(.:format)      {:controller=>"manage/publish", :action=>"destroy"}

这是我想要的路线,只是没有映射到正确的控制器。我已经尝试了所有我能想到的尝试,并允许控制器不带名称空间,但我很难过。

我知道我可以执行以下操作:

get 'manage/features/:feature_id/publish' => "publish#create", :as => "manage_project_publish"

产生:

manage_project_publish GET    /manage/projects/:project_id/publish(.:format)        {:controller=>"publish", :action=>"create"}

但理想情况下,我更喜欢使用嵌套声明(为了便于阅读) - 如果可能的话;我开始认为它不是。

5 个答案:

答案 0 :(得分:12)

资源采用可选的哈希,您可以在其中指定控制器

resource :projects do

将写为

resource :projects, :controller=>:publish do 

答案 1 :(得分:5)

当您需要范围路线但不需要同名模块中的控制器时,请使用scope而不是namespace

答案 2 :(得分:3)

如果我理解你是对的,你想要这个:

scope :manage do
  resources :projects, :only => [] do
    get 'publish' => 'publish#create'
    get 'unpublish' => 'publish#destroy'
  end
end

生产这些路线:

project_publish     GET    /projects/:project_id/publish(.:format)    {:action=>"create", :controller=>"publish"}
project_unpublish   GET    /projects/:project_id/unpublish(.:format)  {:action=>"destroy", :controller=>"publish"}

我是否正确理解您的需求?如果是这样,这就是Ryan正在解释的内容。

答案 3 :(得分:3)

我认为你想要的是:

namespace :manage, module: nil do
  resources :projects do
    get 'publish' => 'publish#create'
    get 'unpublish' => 'publish#destroy'
  end
end

这会根据您的意愿创建命名路由(manage_projects ...),但仍会调用控制器::Publish

答案 4 :(得分:1)

为时已晚,但是对于仍在为此苦苦挣扎的任何人,您都可以在控制器名称前添加一个斜杠,以将其从任何现有名称空间中拉出。

concern :lockable do
  resource :locks, only: [] do
    post "lock" => "/locks#create"
    post "unlock" => "/locks#destroy"
  end
end

现在,如果您在任何地方(无论是否使用命名空间)都包含该问题,您将始终点击LocksController。