views:

64

answers:

3

I am looking for a way to decide the routes based on a request parameter.For example i want to have route a request to web controller if it has params[:web] and to iPhone if it has params[:iphone]. Is it possible to do so keeping the names of the routes same but routing them to different controllers/actions depending upon the parameter?

A: 

Possible if you define route(or a named route) like below in your routes.rb file

map.connect '/:controller/:action/:platform',:controller => 'some controller name',:action=>'some action'

if you handle this in your action, you can use like params[:platform]

Read more on named routes if you customize more on this. As far as your prob is concerned I hope the above code solves the problem

lakshmanan
@lakshmanan this code will point to the same controller but i want to decide the controller on runtime.
Hitesh Manchanda
A: 

Expanding on @lakshmanan's answer, you can do this:

Add this to your routes.rb:

map.named_route '/:controller/:action/:platform'

In your views,

<%= link_to "Blah blah", named_route_path(:controller => "some_controller",
                                          :action => "some_action",
                                          :platform => "some_platform")

In your some_controller,

def some_action
   if params[:platform] == "web"
        #DO SOMETHING
   elsif params[:platform] == "iphone"
        #DO SOMETHING
   else
        #DO SOMETHING
   end
end
Shripad K
There's a bug: you want == "iphone" instead of = "iphone".
etoleb
That won't solve the purpose for me I want the named route to work with same name but different controller action mappings as there are certain extra checks and processing for certain parameters and i do not want to make my code cluttered with conditions in the same action and the response will also vary accordingly.
Hitesh Manchanda
I am still not understanding what you exactly want. Probably if you could explain with pseudo-code, with an example case, it would be just great! Also i would agree with @Eimantas' comment, provided that you have tried it out, and you are sure that, that is not what you want! :)
Shripad K
A: 

Assuming that there is a very good reason to have one controller accept this action (if there is shared code... move it to a helper method or model, and use the user agent info or named routes to your advantage), check the parameter and redirect to the appropriate controller and action:

def some_action 
   # some shared code here
   if params[:platform] == 'iphone'
     redirect_to :controller => 'foo', :action => 'bar'
   elsif params[:platform] == 'web'
     redirect_to :controller => 'baz', :action => 'baq'
   else
     # default controller and action here
   end
end

If you really really want the named route to map to different controllers, you'll need to hardcode the platform string:

map.connect '/foo/bars/:id/iphone', :controller => 'iphone',:action=>'some_action'
map.connect '/foo/bars/:id/web', :controller => 'web',:action=>'some_action'

UPDATE0

From here, you might want to try map.with_options(:conditions => ... )

Terry Lorber