将多个操作路由到同一个控制器和操作

时间:2011-07-09 15:18:52

标签: ruby-on-rails ruby-on-rails-3 routing routes match

我正试图在我的Rails应用程序上运行这样的东西:

match '/:language', :to => 'posts#search_result'
match '/:tag', :to => 'posts#search_result'
match '/:language/:tag', :to => 'posts#search_result'

我正在使用此search_result操作根据语言和标记过滤一些帖子。

问题在于:有时候:标签为零或:语言为零;所以在调用动作时我有这三种可能性:

<%=link_to "Spanish", {:controller => 'posts', :action => 'search_result', :language => "spanish"} %>

<%= link_to "Spanish", {:controller => 'posts', :action => 'search_result', :language => "spanish", :tag => @tag} %>

<%=link_to "#{tag.name}", {:controller => 'posts', :action => 'search_result', :tag => @tag} %>

我希望拥有以下网址:

/spanish          (for the first case)
/spanish/rails    (where rails is a tag, for the second case)
/rails            (for the third case)

但是现在我得到了第一和第三种情况的严格要求,但对于我得到的第二种情况: 的 /西班牙语?标签=轨 或者再次 / spanish (取决于我先选择了一个标签还是先选择了一种语言)。

我希望我能正确解释自己。任何的想法??。谢谢!

2 个答案:

答案 0 :(得分:3)

不是单独定义/:language和/:language /:标签,而是将它们一起定义,使用/:标签作为可选的URI元素。

match '/:language(/:tag)', :to => 'posts#search_result'

我认为路由是按照路由定义的顺序匹配(以及从它们生成的URI)。你在定义/:lang /:tag之前定义了/:lang,所以它匹配/:lang和made:标记一个GET参数。我想你可以优化你的定义的顺序,但我相信使用上面的语法是首选的方法。

答案 1 :(得分:3)

路由器无法区分a:language和a:tag。

只是因为当您在视图中构建代码时,您的路由会说“语言”和“标记”。请记住,在html中,这已经被翻译成普通的URL,例如/ spanish或/ rails

然后必须从此URL中找出路线。

现在正如我所说,路由器无法判断某个单词是一种语言还是一个标签...而且plain-ole-URL没有单词“tag”或者其中的“语言”...所以你的两条路线在这里:

match '/:language', :to => 'posts#search_result'
match '/:tag', :to => 'posts#search_result'

相同类型的网址

斜线后只有一个标记。以下是一些与该路线匹配的示例:

/greek
/spanish
/rails
/urdu
/whatever

他们将所有匹配匹配“斜线后的单个令牌”的第一条路线...这意味着您的路由器将所有路由器匹配到“语言”路线并永远不会匹配“/:tag”路由,因为它已在上面的路由上匹配。

他:他对路由器来说都是希腊人;)

修改

  

嗨,这对我了解路由的工作方式有很大帮助..但我仍然看不清楚。我明白你说了什么,所以基本上我明白我应该做匹配'/ tags /:标签,至少只有路线到帖子#search_result URLS起始/ tag ..什么是解决方案??

是的,“/ tags /:tag”会清晰明确,但如果您希望它在标记与语言方面真正灵活,那么简单来说就更好了:

match '/posts/search', :to => 'posts#search_result'

可以使用上面的任何link_to示例来生成例如:

/posts/search?tag=rails
/posts/search?language=spanish
/posts/search?language=spanish&tag=rails

传达的内容以及为什么更为明确。

第三个网址的描述是“我正在搜索一组有语言=西班牙语和tag = rails的帖子”

您的网址应该反映资源(在这种情况下是一组帖子)其他一切最好以查询参数完成。