最近我在我的一个应用程序中更改了一些嵌套资源以使用浅层路由。它工作得很好,我已经能够简化我的观点和控制器。
但是,我之前一直在使用path_prefix:
map.with_options :path_prefix => "blog" do |blog|
blog.resources :posts do |posts|
posts.resources :comments
end
end
请注意,所有路由均按预期以“/ blog”为前缀。
# $ rake routes
# posts GET /blog/posts(.:format) {:controller=>"posts", :action=>"index"}
# POST /blog/posts(.:format) {:controller=>"posts", :action=>"create"}
# new_post GET /blog/posts/new(.:format) {:controller=>"posts", :action=>"new"}
# edit_post GET /blog/posts/:id/edit(.:format) {:controller=>"posts", :action=>"edit"}
# post GET /blog/posts/:id(.:format) {:controller=>"posts", :action=>"show"}
# PUT /blog/posts/:id(.:format) {:controller=>"posts", :action=>"update"}
# DELETE /blog/posts/:id(.:format) {:controller=>"posts", :action=>"destroy"}
# post_comments GET /blog/posts/:post_id/comments(.:format) {:controller=>"comments", :action=>"index"}
# POST /blog/posts/:post_id/comments(.:format) {:controller=>"comments", :action=>"create"}
# new_post_comment GET /blog/posts/:post_id/comments/new(.:format) {:controller=>"comments", :action=>"new"}
# edit_post_comment GET /blog/posts/:post_id/comments/:id/edit(.:format) {:controller=>"comments", :action=>"edit"}
# post_comment GET /blog/posts/:post_id/comments/:id(.:format) {:controller=>"comments", :action=>"show"}
# PUT /blog/posts/:post_id/comments/:id(.:format) {:controller=>"comments", :action=>"update"}
# DELETE /blog/posts/:post_id/comments/:id(.:format) {:controller=>"comments", :action=>"destroy"}
新的路由配置如下所示:
map.with_options :path_prefix => "blog", :shallow => true do |blog|
blog.resources :posts do |posts|
posts.resources :comments
end
end
现在,我的一些路线中缺少“/ blog”前缀。
# $ rake routes
# posts GET /blog/posts(.:format) {:controller=>"posts", :action=>"index"}
# POST /blog/posts(.:format) {:controller=>"posts", :action=>"create"}
# new_post GET /blog/posts/new(.:format) {:controller=>"posts", :action=>"new"}
# edit_post GET /posts/:id/edit(.:format) {:controller=>"posts", :action=>"edit"}
# post GET /posts/:id(.:format) {:controller=>"posts", :action=>"show"}
# PUT /posts/:id(.:format) {:controller=>"posts", :action=>"update"}
# DELETE /posts/:id(.:format) {:controller=>"posts", :action=>"destroy"}
# post_comments GET /posts/:post_id/comments(.:format) {:controller=>"comments", :action=>"index"}
# POST /posts/:post_id/comments(.:format) {:controller=>"comments", :action=>"create"}
# new_post_comment GET /posts/:post_id/comments/new(.:format) {:controller=>"comments", :action=>"new"}
# edit_comment GET /comments/:id/edit(.:format) {:controller=>"comments", :action=>"edit"}
# comment GET /comments/:id(.:format) {:controller=>"comments", :action=>"show"}
# PUT /comments/:id(.:format) {:controller=>"comments", :action=>"update"}
# DELETE /comments/:id(.:format) {:controller=>"comments", :action=>"destroy"}
我正在寻找一种解决方案来获取所有路线的前缀。我知道它正在使用命名空间(map.namespace :blog do
),但我想阻止重构我的所有控制器/视图/测试以实际使用命名空间。
使用Rails版本2.3.2和Ruby 1.8.7测试所有代码示例。
答案 0 :(得分:6)
文档似乎表明这种确切的行为是设计的:
:shallow - 如果为true,引用特定成员的嵌套资源的路径(即具有:id参数的路径)将不使用父路径前缀或名称前缀。
(来自http://api.rubyonrails.org/classes/ActionController/Resources.html#M000501)
由于使用:shallow选项会导致在某些情况下忽略:path_prefix,如果必须始终使用此前缀,则应考虑删除:shallow选项。这是一个替代解决方案,似乎可以满足您的需求:
map.with_options :path_prefix => "blog" do |blog|
blog.resources :posts do |posts|
posts.resources :comments, :only => [:index, :create, :new]
end
blog.resources :comments, :except => [:index, :create, :new]
end
导致这些路线:
# posts GET /blog/posts {:controller=>"posts", :action=>"index"}
# POST /blog/posts {:controller=>"posts", :action=>"create"}
# new_post GET /blog/posts/new {:controller=>"posts", :action=>"new"}
# edit_post GET /blog/posts/:id/edit {:controller=>"posts", :action=>"edit"}
# post GET /blog/posts/:id {:controller=>"posts", :action=>"show"}
# PUT /blog/posts/:id {:controller=>"posts", :action=>"update"}
# DELETE /blog/posts/:id {:controller=>"posts", :action=>"destroy"}
# post_comments GET /blog/posts/:post_id/comments {:controller=>"comments", :action=>"index"}
# POST /blog/posts/:post_id/comments {:controller=>"comments", :action=>"create"}
# new_post_comment GET /blog/posts/:post_id/comments/new {:controller=>"comments", :action=>"new"}
# edit_comment GET /blog/comments/:id/edit {:controller=>"comments", :action=>"edit"}
# comment GET /blog/comments/:id {:controller=>"comments", :action=>"show"}
# PUT /blog/comments/:id {:controller=>"comments", :action=>"update"}
# DELETE /blog/comments/:id {:controller=>"comments", :action=>"destroy"}
希望这有帮助!
答案 1 :(得分:5)
可能最简单的解决方案不是使用:浅选项,但使用额外的资源定义创建相同的路径:
map.with_options :path_prefix => "blog" do |blog|
blog.resources :posts do |posts|
posts.resources :comments, :only => [:index, :create, :new]
end
end
map.resources :comments, :path_prefix => "blog",
:except => [:index, :create, :new]
给出了以下路线定义:
# $ rake routes
# posts GET /blog/posts(.:format) {:action=>"index", :controller=>"posts"}
# POST /blog/posts(.:format) {:action=>"create", :controller=>"posts"}
# new_post GET /blog/posts/new(.:format) {:action=>"new", :controller=>"posts"}
# edit_post GET /blog/posts/:id/edit(.:format) {:action=>"edit", :controller=>"posts"}
# post GET /blog/posts/:id(.:format) {:action=>"show", :controller=>"posts"}
# PUT /blog/posts/:id(.:format) {:action=>"update", :controller=>"posts"}
# DELETE /blog/posts/:id(.:format) {:action=>"destroy", :controller=>"posts"}
# post_comments GET /blog/posts/:post_id/comments(.:format) {:action=>"index", :controller=>"comments"}
# POST /blog/posts/:post_id/comments(.:format) {:action=>"create", :controller=>"comments"}
# new_post_comment GET /blog/posts/:post_id/comments/new(.:format) {:action=>"new", :controller=>"comments"}
# edit_comment GET /blog/comments/:id/edit(.:format) {:action=>"edit", :controller=>"comments"}
# comment GET /blog/comments/:id(.:format) {:action=>"show", :controller=>"comments"}
# PUT /blog/comments/:id(.:format) {:action=>"update", :controller=>"comments"}
# DELETE /blog/comments/:id(.:format) {:action=>"destroy", :controller=>"comments"}