2010-06-29 42 views
0

嘿!我試圖在Rails應用程序中設置路由,以便根據傳遞的參數類型,Rails將請求發送到不同的操作。Rails:通過檢測參數來映射衝突路由

我有courses它有一個屬性state這是一個字符串與兩個字母的狀態縮寫。當用戶訪問/courses/1時,我希望Rails在courses控制器中顯示show操作(並將參數傳遞爲:id)。但是,當用戶訪問/courses/CO時,我希望Rails顯示index操作並將參數傳遞爲:state

所以/courses/1將相當於

:controller => 'courses', :action => 'show', :id => '1' 

而且/courses/CO將相當於

:controller => 'courses', :action => 'index', :state => 'CO' 

我已經試過這樣:

map.resources :courses, :except => { :index, :show } 
map.connect 'courses/:state', :controller => 'courses', :action => 'index', :state => /[A-Z]{2}/ 
map.connect 'courses/:id', :controller => 'courses', :action => 'show', :id => /[0-9]+/ 

但它打破(Rails服務器不會甚至開始)。我通常不會用路線做這樣的事情,所以我超出了我的技術訣竅。謝謝!

編輯:修正了一個錯字,謝謝JC。

目前的解決辦法是這樣的:

map.resources :courses, :except => [ :index, :show ] 
    map.courses '/courses',  :controller => 'courses', :action => 'index', :state => 'AL', :method => :get 
    map.courses '/courses/:state', :controller => 'courses', :action => 'index', :requirements => { :state => /[A-Z]{2}/ }, :method => :get 
    map.course '/courses/:id', :controller => 'courses', :action => 'show', :requirements => { :id => /[0-9]+/  }, :method => :get 

回答

3

這可行,但你需要去編輯索引的所有鏈接,以說明諸如courses_path('AA')之類的東西,並且你將無法使用一些好幫手,比如form_for,它假定你遵循約定#create只是帶有POST請求的#index。 (使用form_tag獲得舒適)

ActionController::Routing::Routes.draw do |map| 
    map.resources :courses, :except => [ :index, :show ] 
    map.courses '/courses/:state', :controller => 'courses', :action => 'index', :requirements => { :state => /[A-Z]{2}/ } , :method => :get 
    map.course '/courses/:id', :controller => 'courses', :action => 'show', :requirements => { :id => /[0-9]+/  } , :method => :get 
end 

雖然它會保持您的路由命名相同。

(順便說一下,你的/ CO不符合您的正則表達式,這需要大寫字符)


有趣的旁白:我們真的需要一臺路由器的抽象? http://blog.peepcode.com/tutorials/2010/rethinking-rails-3-routes

+0

會允許默認情況下(無參數)阻止我必須更改所有這些鏈接? EG: 'map.connect'/ courses',:controller =>'courses',:action =>'index',:state =>'AL',:method =>:get' – Jay 2010-06-29 15:18:55

0

這恐怕是行不通的,因爲映射路徑的控制器和動作結構的Rails應用程序的啓動設置,參數處理情況在請求時。

您可以做的是將CoursesController的show-action中的id參數與有效狀態列表進行匹配,然後重定向或呈現不同的操作。

希望這會有所幫助。