In a recent project for the New Zealand business community, we were required to have some really custom routes. An example of such routes would be geographical routes, e.g. /china, or /china/beijing.
We could try something like this:
map.country ':country', :controller => :locations, :action => :show,
:country => Regexp.new(Country.all.map(&:name).join('|'))
map.region ':country/:region', :controller => :locations, :action => :show,
:country => Regexp.new(Country.all.each{|c| "^#{c.name}" }.join('|'))
However we get this error “Regexp anchor characters are not allowed in routing requirements”. So we can’t use requirements. However, we can use route conditions instead. With inspiration from Jamis Buck’s route monkeypatch :
# /lib/routing_extensions.rb
module ThongKuah
module Routing
module RouteExtensions
def self.included(base)
base.alias_method_chain :recognition_conditions, :path_regexp
end
# allows recognition for paths only matching the given regexp (conditions[:path])
# allows recognition for paths not matching the given regexp (conditions[:not_path])
def recognition_conditions_with_path_regexp
result = recognition_conditions_without_path_regexp
result << "conditions[:path] =~ path" if conditions[:path]
result << "(conditions[:not_path]=~path).nil?" if conditions[:not_path]
result
end
end
end
end
# /config.environment.rb
require 'route_extension'
ActionController::Routing::Route.send :include, ThongKuah::Routing::RouteExtensions
So now we can go :
map.country ':country', :controller => :locations, :action => :show,
:conditions => {:path => Regexp.new(Country.all.map(&:name).join('|'))}
map.region ':country/:region', :controller => :locations, :action => :show,
:conditions => {:path => Regexp.new(Country.all.each{|c| "^#{c.name}" }.join('|')) }
Note we can have negative matches as well. I’m sure the Regular expressions gods can do a negative match use Regexp only, but hey.
We found this rails idiom to be quite useful as this allows us full customisation of routing, if we need it. We have used it successfully for Made from New Zealand, so you check it out on pages such as www.madefromnewzealand.com/new-zealand and www.madefromnewzealand.com/new-zealand/auckland.
Pastie of the code here.
Sphere: Related Content






