Non-customizable parts in the routes hierarchy-chain

Hi

I created a custom route that looks like this:

map.connect ‘:controller/:table/:action/:id’

Hierarchically, :table is above :action and :id. So, if we call
ActionController::Base#url_for with an argument :table=>nil, we’re
supposed to get a url with :action and :id set to nil as well.
However, this is not the case:

url_for(:table=>nil) from /manager/tables/currency/add/1
returns “/manager/tables/add/1”. In effect, both :action and :id are
treated as if they’re above :table in the hierarchy chain!

I ran a few tests, such as setting the route to
‘:controller/:table/:action/:id/:blah’. And indeed, :table=>nil reset
the lower (right) parts of the route hierarchy except for :action and
:id
. Those seem to always be treated as if they’re above any custom
component I added myself, regardless of how high (left) I placed them
in the route hierarchy.

My questions are:

  1. Is this a bug or a feature?

  2. Is there support for adding custom components to the route that are
    higher than :action and :id?

Alder G. wrote:

Hi

I created a custom route that looks like this:

map.connect ‘:controller/:table/:action/:id’

Hierarchically, :table is above :action and :id. So, if we call
ActionController::Base#url_for with an argument :table=>nil, we’re
supposed to get a url with :action and :id set to nil as well.
However, this is not the case:

url_for(:table=>nil) from /manager/tables/currency/add/1
returns “/manager/tables/add/1”. In effect, both :action and :id are
treated as if they’re above :table in the hierarchy chain!

I ran a few tests, such as setting the route to
‘:controller/:table/:action/:id/:blah’. And indeed, :table=>nil reset
the lower (right) parts of the route hierarchy except for :action and
:id
. Those seem to always be treated as if they’re above any custom
component I added myself, regardless of how high (left) I placed them
in the route hierarchy.

My questions are:

  1. Is this a bug or a feature?

  2. Is there support for adding custom components to the route that are
    higher than :action and :id?

There is nothing special about the ‘:controller/:action:id’ route. It’s
just a route that’s defined in routes.rb

Things to keep in mind…

Once you set a default for one value you will need to for everything to
the right of it or that route will be skipped as not matching.

Unless you removed the default route at the end it’s most likely the one
being used, if I understand your post correctly.

‘/:controller/:table/:action/:id/’, table => nil, :action => nil, :id =>
nil

may achieve what you want.

On 5/14/06, Michael G. [email protected] wrote:

However, this is not the case:
in the route hierarchy.

may achieve what you want.

The more I explore it, the less I understand.

Appearantly you were right, and my route wasn’t even matched. However,
I fail to see why: the default ‘/:controller/:action/:id’ gets matched
even if you only specify a controller. Why does not-specifying a
:table sufficient to prevent matching of the
‘/:controller/:table/:action/:id/’ route?

The minimal additions required to be added to the above code to make
it work, as far as I could determine, were a :table=>nil to the route
and :action=>nil, :id=>nil to the url_for call:

map.connect ‘:controller/:table/:action/:id/’, :table=>nil
url_for(:table=>nil, :action=>nil, :id=>nil)

I have no idea why that works. So I have no idea if what I’m doing
here is a reasonable solution, or a fragile hack that would break on
me a few paces down the road.

Can anyone enlighten?

On 5/14/06, Michael G. [email protected] wrote:

However, this is not the case:
in the route hierarchy.

may achieve what you want.

After a sleepless night of trial & error, I accidently stumbled upon
this strange solution:

url_for(:table=>‘’)

instead of:

url_for(:table=>nil)

I.e. you need to use empty string instead of nil as the argument for
:table. Why that works - I have no idea. ADwR specifically instructs
to assign nil to :table in this case. So either the code was changed
and the book wasn’t updated, or it’s some sort of bug.

Whatever the case may be, ActionController::Routing could use some
official documentation. It currently has none at all. Pretty
problematic, when the un-official material seems to be not merely
lacking but actively misleading. I did have a glance at the source,
and very soon afterwards deferred it to my todo list - definitely not
viable for a sleepless night when you’re already behind schedule ;-).