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

Pet*_*xey 34 routing ruby-on-rails

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

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
Run Code Online (Sandbox Code Playgroud)

但是,此处的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
Run Code Online (Sandbox Code Playgroud)

这有效并产生:

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

但是,如果我尝试:

...
resources :users, :path => '' do
  resources :questions, :path => ''
end
Run Code Online (Sandbox Code Playgroud)

然后事情开始出错了.

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

Dan*_*nne 37

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

resource :users, :path => '' do
  resource :questions, :path => ''
end
Run Code Online (Sandbox Code Playgroud)

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

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

resources :posts
Run Code Online (Sandbox Code Playgroud)

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

编辑:

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


Pet*_*xey 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
Run Code Online (Sandbox Code Playgroud)

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"}
Run Code Online (Sandbox Code Playgroud)