views:

239

answers:

2

Is there a way in the Ruby On Rails Routing framework to make a decision about which controller or action to call based on some logic all within a single route?

For example, let's say have a url zip/354 and I want to call the foo action if the integer is even and the bar action if the integer is odd. To use pseudo-ruby:

map.connect 'zip/:id', :requirements=>{:id=>/^\d+$/} do |id|
  :controller=>'c', :action=>'foo' if id.to_i % 2 == 0
  :controller=>'c', :action=>'bar' if id.to_i % 2 != 0
end
+3  A: 

I am not too sure about the routing side of things but you could have the action call another action based on :id

def zip
  id = params[:id].to_i
  if(id%2 == 0)
    foo
  else
    bar
  end
end

But you may have though of that already.

Will
+1  A: 

I tried a little experiment with my routes and this seemed to work

# route to the even action
map.connect 'foo/:code', :controller => 'bar', 
      :action => 'even', :requirements => { :code => /\d+(2|4|6|8|0)/ }

# route to the odd action
map.connect 'foo/:code', :controller => 'bar', 
      :action => 'odd', :requirements => { :code => /\d+(1|3|5|7|9)/ }

It seems a little hacky to me and I won't argue that it is probably quite fragile, but it does get the job done.

Edit: I didn't put any anchors (^ or $) in the routes because they are not allowed in the Routing requirements. The framework implies that they are there. So according to the routing parser,

/\d+(1|3|5|7|9)/ == /^\d+(1|3|5|7|9)$/
Peer Allan