2010-06-29 23 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参数与有效状态列表进行匹配,然后重定向或呈现不同的操作。

希望这会有所帮助。