This is posted on my blog: http://inquirylabs.com/blog/?p=25
===
Suppose your Ruby on Rails application has several different kinds of
resources that are all identified by GUIDs. For example, several
images, some blog entries, and a few user-generated pages. Now
suppose that you want to access these resources from the URL without
having to identify the resource type in the URL.
Letâ??s say this is an image:
http://localhost:3000/d1e89a06-7524-a97e-3f31-f60e59b3d888
And letâ??s say this is a blog entry:
http://localhost:3000/81f5fb29-0797-7ab3-9890-5377fa416df4
Normally, using Railsâ?? routing system, you wouldnâ??t be able to
distinguish between these two URLs: you would probably force the user
to prepend the resource type, e.g.:
http://localhost:3000/blog/81f5fb29-0797-7ab3-9890-5377fa416df4
Or, you would create a single controller to take the place of the
routing system by rendering components once the resource type is
determined.
Luckily, the routing system is pretty flexible. You can, for example,
use Regular Expressions to match things on the URL and route to
different controllers depending on the result. Now, what if we
subclass Regexp and create our own â??regular expressionâ?? The result
is a simple class that performs one function: it distinguishes
resource types for the routing system.
class ResourceMatcher < Regexp
def initialize(*args)
super(‘^$’)
end
def inspect
"#{self.class}.new"
end
end
class IsBlog < ResourceMatcher
def =~(identifier)
!Blog.find_by_guid(identifier).nil?
end
end
class IsImage < ResourceMatcher
def =~(identifier)
!Image.find_by_guid(identifier).nil?
end
end
Now, in our routes:
ActionController::Routing::Routes.draw do |map|
map.connect ‘:id’,
:id => IsBlog.new,
:controller => ‘blog’,
:action => ‘show’
map.connect ‘:id’,
:id => IsImage.new,
:controller => ‘image’,
:action => ‘show’
end
The reason this works is because (IsBlog.new).is_a?(Regexp) returns
true. If you go into the internals of the routing system, you’ll see
that the ResourceMatcher class is written in just such a way that it
tricks the routing system in to thinking it’s a regular old Regexp.
Once the trickery is in place, we can use the =~ matching method to
return true or false however we please.
Duane J.
(canadaduane)