1

DocumentsController#common_query 可以处理多种不同的请求样式。

即第 4 批中的所有文档或所有标记为“快乐”的文档

我想要一条让它们漂亮的路线,所以:

/documents/common_query?batch=4

/documents/common_query?tag=happy

变得:

/文件/批次/4

/文件/标签/快乐

所以最终结果是调用了#common_query,但部分 url 被用作参数名称,部分被用作它的值。

4

2 回答 2

1

第二个选项,有两个路由,几乎可以肯定是更好的方法,因为它只会匹配你想要支持的 URL 类型,而第一个选项也会“匹配”像 /documents/foo/bar 这样的 URL,这可能会导致您的 #common_query 方法最多返回 RecordNotFound (404) 响应。在最坏的情况下,如果您还没有准备好看不到任何预期的参数,那么您将收到 500 错误...

当然,如果你开始有很多变化,你最终会得到很多路线。如果您需要组合使用它们,例如/documents/batch/4/tag/happy,那么您需要使用通配符路由,并在控制器中进行参数处理。这可能看起来像:

map.connect 'documents/*specs', :controller => "documents_controller", :action => "common_query"

URL 的各种元素将作为 params[:specs] 提供给您的控制器。你可以把它变成这样的发现:

@items = Item.find(:all, :conditions => Hash[params[:specs]])

Hash[] 技术将选项的一维数组转换为键值哈希,即使您不直接将其提供给 find(),这也可能很有用。

于 2008-12-04T11:20:46.247 回答
0

作为单一路线:

ActionController::Routing::Routes.draw do |map|
  map.connect "documents/:type/:id", :controller => "documents_controller", 
              :action => "common_query"
end

那么params[:type]要么是"batch"or "tag"params[:id]要么是"4"or "happy"。您必须确保DocumentsController路由中的其他操作在此之前,因为这将匹配任何看起来像"documents/*/*".

但为什么它必须是单条路线?您可以像这样使用两条路线:

map.with_options(:controller => "documents_controller", 
                 :action => "common_query") do |c|
  c.connect "documents/batch/:page", :type => "batch"
  c.connect "documents/tag/:tag",    :type => "tag"
end

这将具有相同的效果,但更具体,因此您不必担心路线的优先顺序。

于 2008-12-04T08:16:46.820 回答