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

时间:2011-06-16 09:09:29

标签: ruby-on-rails routing

我想减少我的应用程序上的路线,以便:

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

...变为

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

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

基本路线档案

没有任何URL修剪,routes文件如下所示:

...
resources :users do
  resources :questions
end

但是,此处的网址采用

的形式

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

然后事情就开始出错了。

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

4 个答案:

答案 0 :(得分:37)

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

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

另一件可能是原因并且您需要谨慎的是,这些路线几乎捕获了所有请求,您应该在routes.rb中将它们放在最后,以便其他路由首先匹配。以这种情况为例:

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

resources :posts

如果你这样做,那么任何请求都不会被路由到Posts控制器,因为对/ posts / 1的请求将被发送到Questions控制器:user_id => 'posts',:id => 1

编辑:

此外,我现在注意到您使用资源而不是资源。不知道是否有意或是错误。

答案 1 :(得分:6)

感谢@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

Rake Routes输出

    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"}

答案 2 :(得分:4)

不确定嵌套但请尝试

:path => '/'

答案 3 :(得分:0)

以为我会添加另一个可能的解决方案,以防其他人在以后从谷歌到达。

在查看this nested resource article后,这可能是一个更清晰的解决方案,几乎在路线中具有相同的灵活性:

resources :users, :path => ''
resources :users, :path => '', :only => [] do
  resources :questions, :path => '', :except => [:index]

基本上,通过包含第二个父块,子资源不会在父资源之前产生。

这个特殊的例子还假设父母的完整路线比孩子的路线更重要。因此,子块被限制为具有索引,但这可能是可接受的,具体取决于具体情况。