2011-07-09 140 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