使用path_prefix的浅路线?

时间:2009-04-12 12:36:35

标签: ruby-on-rails ruby

最近我在我的一个应用程序中更改了一些嵌套资源以使用浅层路由。它工作得很好,我已经能够简化我的观点和控制器。

但是,我之前一直在使用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测试所有代码示例。

2 个答案:

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