This project is archived and is in readonly mode.
setting "arbitrary" default value on route foils named route generation
Reported by Bill Burcham | September 22nd, 2008 @ 05:22 PM | in 2.x
Setting an "arbitrary" (i.e. not represented in the path)
default value on a route (:name => value
e.g.
:layout => 'home'
) is described on pp 397-398 of
the "Defining Routes with map.connect" section of chapter 20.2
"Routing Requests" of "Agile Web Development with Rails" second
edition.
An "arbitrary" default value is one whose name does not appear as a tag in the path specification pattern. Here is an example (from routes.rb):
map.home_index '', :controller => 'home',
:extra_stuff => 'the_stuff'
This is useful for e.g. dynamically setting the layout based on the route:
map.home_index '', :controller => 'home',
:layout => 'home_layout'
And then using the value set in the route, to set the layout on a controller like so:
layout proc{ |controller| controller.params[:layout]}
In Rails 2.1.0 this sort of route recognition works great. But when a route has "arbitrary" default values, route generation does not work (for that route). In order to get route generation to work for such a route, all the "arbitrary" default values must be specified to the generator. The problem is that these default values are not known and should not be known at the point of the generating call.
Here is a project that illustrates the issue:
http://github.com/Bill/arbitrary...
Run:
rake test
And you'll see the failure. Important files are:
/config/routes.rb /test/functional/home_test.rb
The first test demonstrates the workaround (of explicitly specifying the "arbitrary" default values to the generate call) and the second test demonstrated the failure.
Comments and changes to this ticket
-
Bill Burcham December 23rd, 2008 @ 05:27 PM
- Assigned user set to Pratik
Thank you for looking into this Pratik, however, you misunderstood the issue. Using :defaults doesn't help because the variable whose value I wish to set is not in the path (pattern).
In my example the variable was named :extra_stuff. If I change my route to this as you suggest:
map.home_index '', :controller => 'home', :defaults => {:extra_stuff => 'the_stuff'}
And re-run my test:
def test_index_no_explicit_extra_stuff # but URL generation fails if we leave it off assert_generates( '/', :controller => 'home', :action => 'index') end
I see this error now:
/builder.rb:117:in `assign_route_options': extra_stuff: No matching segment exists; cannot assign default (ArgumentError)
See "no matching segment exists". The whole point is that I wish to set a variable when a match happens. That variable is not part of the original path. The "Agile" book says this is possible (see reference above) and I've found it useful for e.g. setting the layout and for setting other static values that vary based on which routing rule fires.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
People watching this ticket
Referenced by
- 2478 :defaults not in path cause "No matching segment exists" error This ticket is related to #1092 (closed invalid).
- 2478 :defaults not in path cause "No matching segment exists" error The reviewer of #1092 suggested I use :defaults in routes...
- 2478 :defaults not in path cause "No matching segment exists" error That's just the behavior I described in my December 23 co...
- 2478 :defaults not in path cause "No matching segment exists" error The behavior described in the Agile book (see #1092) cont...
- 2478 :defaults not in path cause "No matching segment exists" error Furthermore, the alternative suggested by the reviewer of...