Conditional dynamic routes using constraints

Yatish Mehta
March 17, 2013

Rails routes is used to map the ‘url’ with corresponding controller action. It is similar to .htaccess in the PHP world. There are conditions when the same url-pattern needs to be mapped to different actions.

Consider the following the example

`match "/:search" => "companies#show"`

This route maps to the show action of companies_controller. If we have a scenario where depending on the pattern of :search the controller action needs to be decided. If it matches a particular Regular expression rule, it maps to action1 else action2.

if :search.match/PATTERN/
  match /:search => 'companies#show'
else
  match /:search => 'technologies#show'
end

We can map it to single controller action and redirect it depending on the pattern from the controller.

This can also be achieved using the constraints introduced in Rails 3

match "/:search" => 'companies#show', constraints: { search: /.*\..*/ }
match "/:search" => 'technologies#show'

Let us assume there is complex logic which decides the constraints of the routes, then the following method can be used.

Create a module or class with the self.matches? method. Use this method in the constraint’s hash.

class PatternConstraint
  def self.matches?(request)
    #
    # Any complex logic
    #
    request.path_parameters['search'].match(/REGEXP_PATTERN/)
  end
end

and in the routes.rb

match "/:search" => 'companies#show', constraints: PatternConstraint.new
match "/:search" => 'technologies#show'

One more reason to shout “Ruby on Rails is awesome”

If you would like to reach out to me, I am @yatish27 on Twitter. Feel free to give a shout out.