How to match dynamic named routes in Rails 3

Hi everyone,

I've been digging pretty deeply into the new routing capabilities in Rails 3 and have been very impressed by what I've seen so far. However, in my exploration I haven't been able to figure out one final piece — it's a bit complicated to summarize, so here's a short example of what I would like to do:

Let's say I've got a simple set of forums software, with a controller named Forum. In the data model that Forum uses, there are a bunch of topics with subtopics:

Foo   >--- Bar   >--- Baz          >--- Rick          >--- Astley

Although that's the way the structure looks today, there's nothing that would prevent an admin from adding topics under "Bar" at a moment's notice — so the main point is that the structure could change.

I'd like to be able to write a routing rule such that I could match "http://example.com/Foo/Baz/Rick" to a specific action in the Forum controller and know the order of the parameters that were passed in. In a perfect world, I'd really only like to forward the request on to the Forum controller if the path is sensible. I have some feeling that I might be able to do something creative with :constraints, but I'm not quite sure if I can pass in an appropriate method or proc that would have access to the necessary data to do that check.

Can anyone out there with some better insight point me in the right direction?

-Jury

Well in Rails 2.x you could use something like this (from the rails guide example):

map.connect 'photo/*other', :controller => 'photos', :action => 'unknown'

this would set params[:other] to an array of the path segments following photo.

I applied this thinking to Rails 3 routing, and added a route to a version of the AWDWR depot app (I'm once again following that example through the new beta version of the 4th edition). I put this at the end.

  match '*path' => 'products#forum'

I then added a forum action to the products controller which just raises an exception so that I can see what the params are, and I get this:

  {"path"=>"products/forum/a/b/c"}

So instead of breaking it down to an array it just gives you the whole string.

Some caveats.

1) Although the existing routes still work since I put this at the end of the routes, unless this is the only controller you have you might want to 'anchor' such urls with a first path component (e.g. forum).

2) Whether or not the fact that a 'globbed' route produces a string rather than an array, might or might not be a bug in Rails 3.0.0.beta3     so it might change before release 1.