我正试图在我的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 (取决于我先选择了一个标签还是先选择了一种语言)。
我希望我能正确解释自己。任何的想法??。谢谢!
答案 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的帖子”
您的网址应该反映资源(在这种情况下是一组帖子)其他一切最好以查询参数完成。