diff --git a/actionpack/lib/action_dispatch/routing/redirection.rb b/actionpack/lib/action_dispatch/routing/redirection.rb index 3e2a9e232d52f..b3823bb496cfa 100644 --- a/actionpack/lib/action_dispatch/routing/redirection.rb +++ b/actionpack/lib/action_dispatch/routing/redirection.rb @@ -37,10 +37,25 @@ def path(params, request) end def inspect - "Redirect (#{status})" + "redirect(#{status})" end end + class PathRedirect < Redirect + def path(params, request) + (params.empty? || !block.match(/%\{\w*\}/)) ? block : (block % escape(params)) + end + + def inspect + "redirect(#{status}, #{block})" + end + + private + def escape(params) + Hash[params.map{ |k,v| [k, Rack::Utils.escape(v)] }] + end + end + class OptionRedirect < Redirect # :nodoc: alias :options :block @@ -60,6 +75,10 @@ def path(params, request) ActionDispatch::Http::URL.url_for url_options end + def inspect + "redirect(#{status}, #{options.map{ |k,v| "#{k}: #{v}" }.join(', ')})" + end + private def escape_path(params) Hash[params.map{ |k,v| [k, URI.parser.escape(v)] }] @@ -106,24 +125,15 @@ module Redirection def redirect(*args, &block) options = args.extract_options! status = options.delete(:status) || 301 + path = args.shift return OptionRedirect.new(status, options) if options.any? - - path = args.shift - - block = lambda { |params, request| - (params.empty? || !path.match(/%\{\w*\}/)) ? path : (path % escape(params)) - } if String === path + return PathRedirect.new(status, path) if String === path block = path if path.respond_to? :call raise ArgumentError, "redirection argument not supported" unless block Redirect.new status, block end - - private - def escape(params) - Hash[params.map{ |k,v| [k, Rack::Utils.escape(v)] }] - end end end end diff --git a/railties/lib/rails/application/route_inspector.rb b/railties/lib/rails/application/route_inspector.rb index 845c54f4162c8..b23fb3e920002 100644 --- a/railties/lib/rails/application/route_inspector.rb +++ b/railties/lib/rails/application/route_inspector.rb @@ -16,7 +16,7 @@ def rack_app(app = self.app) class_name = app.class.name.to_s if class_name == "ActionDispatch::Routing::Mapper::Constraints" rack_app(app.app) - elsif class_name == "ActionDispatch::Routing::Redirect" || class_name !~ /^ActionDispatch::Routing/ + elsif ActionDispatch::Routing::Redirect === app || class_name !~ /^ActionDispatch::Routing/ app end end diff --git a/railties/test/application/route_inspect_test.rb b/railties/test/application/route_inspect_test.rb index 31af1ca6dcac6..3b8c874b5b0c6 100644 --- a/railties/test/application/route_inspect_test.rb +++ b/railties/test/application/route_inspect_test.rb @@ -155,11 +155,14 @@ def test_rake_routes_dont_show_app_mounted_in_assets_prefix def test_redirect output = draw do - match '/foo' => redirect("/bar") - match '/foo2' => redirect("/bar", status: 307) + get "/foo" => redirect("/foo/bar"), :constraints => { :subdomain => "admin" } + get "/bar" => redirect(path: "/foo/bar", status: 307) + get "/foobar" => redirect{ "/foo/bar" } end - assert_equal " foo /foo(.:format) Redirect (301)", output[0] - assert_equal "foo2 /foo2(.:format) Redirect (307)", output[1] + + assert_equal " foo GET /foo(.:format) redirect(301, /foo/bar) {:subdomain=>\"admin\"}", output[0] + assert_equal " bar GET /bar(.:format) redirect(307, path: /foo/bar)", output[1] + assert_equal "foobar GET /foobar(.:format) redirect(301)", output[2] end end end