2011-07-09 105 views
3

我试图得到这样的工作对我的Rails应用程序:路由多个动作相同的控制器和动作

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

我用这search_result行动,以过滤取决于语言的一些职位,标签。

问题是,有时:标签将为零或:语言将为零;所以调用的动作时,我有这3种可能性:

<%=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?tag = rails 或再次/西班牙语(取决于我是否先选择了标记或语言)。

我希望我解释自己的权利。任何想法??。谢谢!。

回答

3

路由器无法区分a:language和a:tag之间的区别。

仅仅因为你的路线说“语言”和“标签”,当你在视图构建你的代码..记得在HTML这已被翻译成只是普通的OLE网址,例如:/西班牙/或轨道

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

现在,就像我说的,路由器不能告诉一个特定的词语言或标签......而纯OLE-URL没有单词“标签”或“语言”在它了...所以你两条路在这里:

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

相同样的URL

只是斜线后单个标记的两个。下面是一些例子,这将匹配路线:

/greek 
/spanish 
/rails 
/urdu 
/whatever 

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

他他:这是所有希腊到路由器;)

编辑:

嗨,这是帮助我很多了解路由工作..但我仍然无法看清楚。我明白你说的,所以基本上我明白我应该做一些像'/ tags /:tag至少只是路由到帖子#search_result URL /开始的标签..什么是解决方案?

是,“/标签/:标签”将是明确无误的,但如果你希望它在标签VS你会用简单的得到更好的服务语言真正灵活:

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

这可以使用任何你的link_to以上示例产生如:

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

它也更清楚被传递什么和为什么

第三URL的描述是“我在寻找一组具有语言=西班牙语和标签帖=轨”

您的网址应反映资源(在这种情况下是一组职位)一切都更好地完成查询参数。

+0

嗨,这帮助我了解了路由是如何工作的......但仍然看不清楚。我明白你说的话,所以基本上我明白我应该做一些类似'match'/ tags /:tag'的东西,至少只能发布帖子。#search_result以/ tag开头的URL。什么是解决方案?如果路由器在language:和tag之间没有区别,为什么这两行会给出不同的行为?:'match'/:language(/:tag)',:to =>'posts#search_result'' and'match '/:tag(/:language)',:to =>'posts#search_result'' – diegopau

+0

已添加到我的答案中以反映更好的解决方案。我不知道为什么后两者会有不同的表现 - 但最终,这并不重要 - 它们不是您所需路线的最佳/最具说明性的选择。 –

+0

你能告诉我你的两个新例子的不同行为是什么? –

3

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

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

相信路由匹配的(和由它们产生的URI)的顺序中的路由被定义。您在定义/:lang /:标记之前定义了/:lang,因此它与/:lang匹配并使得:标记GET参数。我想你可以优化你的定义的顺序,但我相信使用上面的语法是首选的方法。

+0

'match'/:language(/:tag)',:to =>'posts#search_result''我第一次选择标签时遇到了问题。但是,这是两条线的匹配方式:匹配/语言(/:标签)',:到=>'帖子#搜索结果'和'匹配'/:标签(/:语言)', :to =>'posts#search_result''我涵盖了所有的情况,并且工作完美。没有你的帮助,找不到它。谢谢。 ' – diegopau