提交 bcfbd8ba 编写于 作者: M Matthew Erhard

Fix mounted engine named routes regression

When generating the url for a mounted engine through its proxy, the path should be the sum of three parts:

1. Any `SCRIPT_NAME` request header or the value of `ActionDispatch::Routing::RouteSet#relative_url_root`.
2. A prefix (the engine's mounted path).
3. The path of the named route inside the engine.

Since commit https://github.com/rails/rails/commit/44ff0313c121f528a68b3bd21d6c7a96f313e3d3, this has been broken. Step 2 has been changed to:

2. A prefix (the value of `ActionDispatch::Routing::RouteSet#relative_url_root` + the engine's mounted path).

The value of `ActionDispatch::Routing::RouteSet#relative_url_root` is taken into account in step 1 of the route generation and should be ignored when generating the mounted engine's prefix in step 2.

This commit fixes the regression by having `ActionDispatch::Routing::RouteSet#url_for` check `options[:relative_url_root]` before falling back to `ActionDispatch::Routing::RouteSet#relative_url_root`. The prefix generating code then sets `options[:relative_url_root]` to an empty string. This empty string is used instead of `ActionDispatch::Routing::RouteSet#relative_url_root` and avoids the duplicate `relative_url_root` value in the final result.

This resolves #20920 and resolves #21459
上级 e70ec9e9
* Fix regression in mounted engine named routes generation for app deployed to
a subdirectory. `relative_url_root` was prepended to the path twice (e.g.
"/subdir/subdir/engine_path" instead of "/subdir/engine_path")
Fixes #20920. Fixes #21459.
*Matthew Erhard*
* ActionDispatch::Response#new no longer applies default headers. If you want
default headers applied to the response object, then call
`ActionDispatch::Response.create`. This change only impacts people who are
......
......@@ -665,6 +665,7 @@ def optimize_routes_generation?; false; end
super(options)
else
prefix_options = options.slice(*_route.segment_keys)
prefix_options[:relative_url_root] = ''.freeze
# we must actually delete prefix segment keys to avoid passing them to next url_for
_route.segment_keys.each { |k| options.delete(k) }
_routes.url_helpers.send("#{name}_path", prefix_options)
......
......@@ -656,14 +656,18 @@ def generate(route_key, options, recall = {})
RESERVED_OPTIONS = [:host, :protocol, :port, :subdomain, :domain, :tld_length,
:trailing_slash, :anchor, :params, :only_path, :script_name,
:original_script_name]
:original_script_name, :relative_url_root]
def optimize_routes_generation?
default_url_options.empty?
end
def find_script_name(options)
options.delete(:script_name) || relative_url_root || ''
options.delete(:script_name) || find_relative_url_root(options) || ''
end
def find_relative_url_root(options)
options.delete(:relative_url_root) || relative_url_root
end
def path_for(options, route_name = nil)
......
......@@ -1304,6 +1304,55 @@ def index
assert_equal '/foo/bukkits/bukkit', last_response.body
end
test "paths are properly generated when application is mounted at sub-path and relative_url_root is set" do
add_to_config "config.relative_url_root = '/foo'"
@plugin.write "lib/bukkits.rb", <<-RUBY
module Bukkits
class Engine < ::Rails::Engine
isolate_namespace Bukkits
end
end
RUBY
app_file "app/controllers/bar_controller.rb", <<-RUBY
class BarController < ApplicationController
def index
render text: bukkits.bukkit_path
end
end
RUBY
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
get '/bar' => 'bar#index', :as => 'bar'
mount Bukkits::Engine => "/bukkits", :as => "bukkits"
end
RUBY
@plugin.write "config/routes.rb", <<-RUBY
Bukkits::Engine.routes.draw do
get '/bukkit' => 'bukkit#index'
end
RUBY
@plugin.write "app/controllers/bukkits/bukkit_controller.rb", <<-RUBY
class Bukkits::BukkitController < ActionController::Base
def index
render text: main_app.bar_path
end
end
RUBY
boot_rails
get("/bukkits/bukkit", {}, {'SCRIPT_NAME' => '/foo'})
assert_equal '/foo/bar', last_response.body
get("/bar", {}, {'SCRIPT_NAME' => '/foo'})
assert_equal '/foo/bukkits/bukkit', last_response.body
end
private
def app
Rails.application
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册