Ruby on rails 如何从rails路由中删除控制器名称?

Ruby on rails 如何从rails路由中删除控制器名称?,ruby-on-rails,routing,Ruby On Rails,Routing,我想减少我申请表中的路线,以便: http://myapplication.com/users/peter/questions/how-do-i-create-urls 变成 http://myapplication.com/peter/how-do-i-create-urls 我有一个用户控制器,希望它是足智多谋的。用户还有一个嵌套资源,称为“问题” 基本路线文件 # setup the basic resources while holding some back for creation

我想减少我申请表中的路线,以便:

http://myapplication.com/users/peter/questions/how-do-i-create-urls

变成

http://myapplication.com/peter/how-do-i-create-urls

我有一个用户控制器,希望它是足智多谋的。用户还有一个嵌套资源,称为“问题”

基本路线文件

# setup the basic resources while holding some back for creation below
resources :users, :except => [:show, :index, :new, :create], :path => '/' do
  resources :questions, :except => [:show]
end

# for clarity, pick out routes that would otherwise go 
# to root (such as new_user => '/new')
resources :users, :only => [:index, :new, :create]


# setup questions#show to give clean URLS
match ':user_id/:question_id', :as => :user_question, 
                               :via => :get,
                               :controller => :questions, 
                               :action => :show

# setup users#show method to give clean URLS
match ':user_id', :as => :user, 
                  :via => :get, 
                  :controller => :user, 
                  :action => :show
没有任何URL修剪,路由文件如下所示:

...
resources :users do
  resources :questions
end
resource :users, :path => '' do
  resource :questions, :path => ''
end
但是,此URL的形式为

http://myapplication.com/users/peter/questions/how-do-i-create-urls

而不是

http://myapplication.com/peter/how-do-i-create-urls

部分成功 我尝试了以下几点:

...
resources :users, :path => '' do
  resources :questions
end
这项工作产生了:

http://myapplication.com/peter/questions/how-do-i-create-urls

但是,如果我尝试:

...
resources :users, :path => '' do
  resources :questions, :path => ''
end
然后事情开始出错


这是正确的方法吗?如果是的话,是否也可以使用嵌套资源?

不确定嵌套,但请尝试

:path => '/'

你这样做应该是可行的。我不知道您遇到了什么问题,但如果您直接从应用程序中复制示例代码,则可能是因为您在路由中添加了额外的
end
。它应该是这样的:

...
resources :users do
  resources :questions
end
resource :users, :path => '' do
  resource :questions, :path => ''
end
另一个可能是原因,您需要注意的是,这些路由几乎捕获所有请求,您应该将它们放在routes.rb的最后,以便其他路由首先匹配。以这个场景为例:

resource :users, :path => '' do
  resource :questions, :path => ''
end

resources :posts
如果这样做,则不会将任何请求路由到Posts控制器,因为发送到/Posts/1的请求将被发送到问题控制器:user_id=>'Posts',:id=>1

编辑:


另外,我现在注意到您使用的是资源而不是资源。不知道这是有意的还是错误的。

感谢@mark和@DanneManne的帮助。有了他们的输入,再加上一点调整,我就把一切都做好了。这并不简单,但我不确定您是否可以将其缩短:


最终工作代码

# setup the basic resources while holding some back for creation below
resources :users, :except => [:show, :index, :new, :create], :path => '/' do
  resources :questions, :except => [:show]
end

# for clarity, pick out routes that would otherwise go 
# to root (such as new_user => '/new')
resources :users, :only => [:index, :new, :create]


# setup questions#show to give clean URLS
match ':user_id/:question_id', :as => :user_question, 
                               :via => :get,
                               :controller => :questions, 
                               :action => :show

# setup users#show method to give clean URLS
match ':user_id', :as => :user, 
                  :via => :get, 
                  :controller => :user, 
                  :action => :show
耙路由输出

    user_questions GET    /:user_id/questions(.:format)          {:action=>"index", :controller=>"questions"}
                   POST   /:user_id/questions(.:format)          {:action=>"create", :controller=>"questions"}
 new_user_question GET    /:user_id/questions/new(.:format)      {:action=>"new", :controller=>"questions"}
edit_user_question GET    /:user_id/questions/:id/edit(.:format) {:action=>"edit", :controller=>"questions"}
     user_question PUT    /:user_id/questions/:id(.:format)      {:action=>"update", :controller=>"questions"}
                   DELETE /:user_id/questions/:id(.:format)      {:action=>"destroy", :controller=>"questions"}
         edit_user GET    /:id/edit(.:format)                    {:action=>"edit", :controller=>"users"}
              user PUT    /:id(.:format)                         {:action=>"update", :controller=>"users"}
                   DELETE /:id(.:format)                         {:action=>"destroy", :controller=>"users"}
             users GET    /users(.:format)                       {:action=>"index", :controller=>"users"}
                   POST   /users(.:format)                       {:action=>"create", :controller=>"users"}
          new_user GET    /users/new(.:format)                   {:action=>"new", :controller=>"users"}
     user_question GET    /:user_id/:question_id(.:format)       {:controller=>"questions", :action=>"show"}
              user GET    /:user_id(.:format)                    {:controller=>"user", :action=>"show"}

我想我会添加另一个可能的解决方案,以防以后有人从谷歌来

经过研究,这可能是一种更清洁的解决方案,在路线上具有几乎相同的灵活性:

resources :users, :path => ''
resources :users, :path => '', :only => [] do
  resources :questions, :path => '', :except => [:index]
基本上,通过包含第二个父块,子资源不会先于父资源生成


此特定示例还假设父块的完整布线比子块的布线更重要。因此,子块的索引受到限制,但这可能是可以接受的,具体取决于具体情况。

Danne,这非常有帮助且令人放心。你在资源的多元化和额外目的上都是对的,我已经解决了这两个问题。在做rake路由时,我还发现它们看起来和预期的一样,但是
user\u问题
实际上是在
user
之前匹配的,所以我将尝试删除(多余的)
user\u问题
路由。另一方面,您知道如何更改传递给控制器的参数变量的键,以便它可以是
:user\u slug
,而不仅仅是
:id
?在
user
之前映射
user\u questions
并不奇怪,因为路由映射器将在添加资源路由之前捕获块。你对此无能为力,无论如何也不会造成任何问题。关于:id参数,我并不知道。我从未见过任何改变它的方法,但我不确定。它对我来说很有魅力。它保持着宁静的精神。我喜欢。