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

On Tue, Apr 27, 2010 at 6:06 PM, Jury [email protected] wrote:

topics with subtopics:
change.
Can anyone out there with some better insight point me in the right
direction?

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.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale