【问题标题】:Shallow routes with path_prefix?带有 path_prefix 的浅路径?
【发布时间】:2009-04-12 12:36:34
【问题描述】:

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

不过,我之前一直在使用 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 进行了测试。

【问题讨论】:

  • 嗨,克里斯托夫,如果我的回答还不够,我可能会提供更多帮助,但您能否说明一下您正在寻找的最终结果以及您对理想解决方案的任何标准?您尝试通过进行此更改来解决的原始测试问题是什么?
  • 其实很简单:在我的示例中,我正在尝试使用 static 路径前缀(例如“/blog”)创建浅层路由。
  • Raimonds 的回答是否符合您的要求?如果没有,您正在寻找的具体路线是什么?
  • 是的,它正在做我想做的事。
  • 感谢您的信息,结果我更新了我的答案。

标签: ruby-on-rails ruby


【解决方案1】:

文档似乎表明这种确切的行为是设计使然:

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

希望这会有所帮助!

【讨论】:

  • 您将我提出的解决方案复制并粘贴到您的答案中似乎有点奇怪。我猜你非常想要这 100 个奖励积分,以至于想尽一切办法来赚取它们 :)
  • Raimonds 我确实看到 Christoph 提到您的回答很有帮助。我觉得它非常接近理想,但为了提供有用的答案,可以通过使其更简洁来稍微改进它。如有冒犯,我深表歉意;这不是故意的。感谢您的帮助。
  • 好的,一切都很好 :) 我也同意在 map.with_options 块中移动最后一行在可读性方面是好的。
【解决方案2】:

可能最简单的解决方案不是使用 :shallow 选项,而是使用额外的资源定义创建相同的路由:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    • 1970-01-01
    • 2018-03-18
    • 2012-11-16
    • 1970-01-01
    • 2013-11-05
    相关资源
    最近更新 更多