This project is archived and is in readonly mode.
Routing bug when using :constraints
Reported by Fouad Mardini | July 20th, 2010 @ 10:25 AM | in 3.0.2
When matching a request fails due to a constraints proc, the
next routes gets params with names as in the failing previous
routing rule
Steps to recreate are below
rails new routing_bug -O --edge
cd routing_bug
rails g controller home
rm public/index.html
## edit config/routes.rb to the following
RoutingBug::Application.routes.draw do
scope "/:country", :constraints => Proc.new { |req| %w[all France Italy Spain].include?(req.symbolized_path_parameters[:country]) } do
match "/", :to => "home#index"
match "/cities", :to => "home#cities"
end
match '/:invalid_country(/*other)', :to => redirect { |params, req|
Rails.logger.warn("~~~~ " + params.inspect)
# "/all" + params[:other]
"/all"
}
end
## Edit app/controllers/home_controller.rb to the following
class HomeController < ApplicationController
def index
render :text => params.inspect
end
def cities
render :text => params.inspect
end
end
$ curl -I localhost:3000/France HTTP/1.1 200 OK
Etag: "e85a20831b64f267c5f41eef6356c95b"
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
Date: Tue, 20 Jul 2010 09:09:38 GMT
Server: WEBrick/1.3.1 (Ruby/1.8.7/2009-06-12)
X-Runtime: 0.012149
Content-Length: 0
Cache-Control: max-age=0, private, must-revalidate
$ curl -I localhost:3000/Germany HTTP/1.1 301 Moved
Permanently
Location: http://localhost:3000/all
Connection: Keep-Alive
Content-Type: text/html
Date: Tue, 20 Jul 2010 09:09:45 GMT
Server: WEBrick/1.3.1 (Ruby/1.8.7/2009-06-12)
X-Runtime: 0.000981
Content-Length: 17
But I would get this in the log
~~~~ {:controller=>"home", :action=>"index",
:country=>"Germany"} The behavior I'm trying to achieve is to
redirect the users to /all/REST_OF_URL whenever they go to an
invalid country
I hacked around it by playing with req.path
Comments and changes to this ticket
-
Fouad Mardini July 20th, 2010 @ 10:26 AM
- no changes were found...
-
Andrew White August 20th, 2010 @ 07:42 AM
- Milestone cleared.
- State changed from new to open
- Assigned user set to Andrew White
- Tag set to rails 3.0, parameters, routing
- Importance changed from to High
What's happening is that the symbolized path parameters are getting cached in the rack environment hash so when you use them in your redirect you get the params from the first route that matches. As a workaround the routes below do what you want them to do.
RoutingBug::Application.routes.draw do scope "/:country", :country => /all|France|Italy|Spain/ do match "/", :to => "home#index" match "/cities", :to => "home#cities" end match '/:invalid_country', :to => redirect("/all") match '/:invalid_country/cities', :to => redirect("/all/cities") end
The string key path parameters hash is correct so you could use that.
-
Fouad Mardini August 21st, 2010 @ 03:27 PM
Thanks Andrew! Unfortunately, my logic is a bit more involved and the regexp won't do
-
Andrew White August 22nd, 2010 @ 06:58 PM
- Assigned user changed from Andrew White to José Valim
Attached patch fixes the issue by caching the symbolized path parameters in the request object rather than the environment hash.
-
Repository August 22nd, 2010 @ 08:17 PM
- State changed from open to resolved
(from [ae2c60734a0f71593709608710a0c7507bb8699e]) Cache the symbolized path parameters using a instance variable in the request object rather than the environment hash. This it to prevent stale parameters in later routing constraints/redirects as only the normal path parameters are set by Rack::Mount.
Also if a constraint proc arity is more than one, pass the symbolized path parameters
as the first argument to match redirect proc args and provide easier access.[#5157 state:resolved]
Signed-off-by: José Valim jose.valim@gmail.com
http://github.com/rails/rails/commit/ae2c60734a0f71593709608710a0c7... -
Repository August 22nd, 2010 @ 08:18 PM
(from [df0a7bfb8fa3f0255fe4ab082863f27c43c278d9]) Cache the symbolized path parameters using a instance variable in the request object rather than the environment hash. This it to prevent stale parameters in later routing constraints/redirects as only the normal path parameters are set by Rack::Mount.
Also if a constraint proc arity is more than one, pass the symbolized path parameters
as the first argument to match redirect proc args and provide easier access.[#5157 state:resolved]
Signed-off-by: José Valim jose.valim@gmail.com
http://github.com/rails/rails/commit/df0a7bfb8fa3f0255fe4ab082863f2...
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
Attachments
Tags
Referenced by
- 5157 Routing bug when using :constraints [#5157 state:resolved]
- 5157 Routing bug when using :constraints [#5157 state:resolved]