Alder Green
2006-May-13 22:14 UTC
[Rails] 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
Michael Greenly
2006-May-13 22:54 UTC
[Rails] Re: Non-customizable parts in the routes hierarchy-chain.
Alder Green 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. -- Posted via http://www.ruby-forum.com/.
Alder Green
2006-May-14 02:00 UTC
[Rails] Re: Non-customizable parts in the routes hierarchy-chain.
On 5/14/06, Michael Greenly <mgreenly@gmail.com> wrote:> Alder Green 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 evanescence 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. >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? -- -Alder
Alder Green
2006-May-14 07:56 UTC
[Rails] Re: Non-customizable parts in the routes hierarchy-chain.
On 5/14/06, Michael Greenly <mgreenly@gmail.com> wrote:> Alder Green 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. >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 ;-). -- -Alder