提交 c8ce3459 编写于 作者: R Rafael França 提交者: GitHub

Merge pull request #29662 from deivid-rodriguez/engine_multiple_mount_points

Allow mounting same engine under several locations
......@@ -652,18 +652,25 @@ def app_name(app, rails_app)
def define_generate_prefix(app, name)
_route = @set.named_routes.get name
_routes = @set
app.routes.define_mounted_helper(name)
script_namer = ->(options) do
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)
end
app.routes.define_mounted_helper(name, script_namer)
app.routes.extend Module.new {
def optimize_routes_generation?; false; end
define_method :find_script_name do |options|
if options.key? :script_name
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)
script_namer.call(options)
end
end
}
......
......@@ -449,7 +449,7 @@ def mounted_helpers
MountedHelpers
end
def define_mounted_helper(name)
def define_mounted_helper(name, script_namer = nil)
return if MountedHelpers.method_defined?(name)
routes = self
......@@ -457,7 +457,7 @@ def define_mounted_helper(name)
MountedHelpers.class_eval do
define_method "_#{name}" do
RoutesProxy.new(routes, _routes_context, helpers)
RoutesProxy.new(routes, _routes_context, helpers, script_namer)
end
end
......
......@@ -8,9 +8,10 @@ class RoutesProxy #:nodoc:
attr_accessor :scope, :routes
alias :_routes :routes
def initialize(routes, scope, helpers)
def initialize(routes, scope, helpers, script_namer = nil)
@routes, @scope = routes, scope
@helpers = helpers
@script_namer = script_namer
end
def url_options
......@@ -29,7 +30,9 @@ def method_missing(method, *args)
self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{method}(*args)
options = args.extract_options!
args << url_options.merge((options || {}).symbolize_keys)
options = url_options.merge((options || {}).symbolize_keys)
options.reverse_merge!(script_name: @script_namer.call(options)) if @script_namer
args << options
@helpers.#{method}(*args)
end
RUBY
......
* Allow mounting the same engine several times in different locations.
Fixes #20204.
*David Rodríguez*
* Clear screenshot files in `tmp:clear` task.
*Yuji Yaginuma*
......
......@@ -1341,6 +1341,92 @@ def index
assert_equal "/foo/bukkits/bukkit", last_response.body
end
test "isolated engine can be mounted under multiple static locations" do
app_file "app/controllers/foos_controller.rb", <<-RUBY
class FoosController < ApplicationController
def through_fruits
render plain: fruit_bukkits.posts_path
end
def through_vegetables
render plain: vegetable_bukkits.posts_path
end
end
RUBY
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
scope "/fruits" do
mount Bukkits::Engine => "/bukkits", as: :fruit_bukkits
end
scope "/vegetables" do
mount Bukkits::Engine => "/bukkits", as: :vegetable_bukkits
end
get "/through_fruits" => "foos#through_fruits"
get "/through_vegetables" => "foos#through_vegetables"
end
RUBY
@plugin.write "config/routes.rb", <<-RUBY
Bukkits::Engine.routes.draw do
resources :posts, only: :index
end
RUBY
boot_rails
get("/through_fruits")
assert_equal "/fruits/bukkits/posts", last_response.body
get("/through_vegetables")
assert_equal "/vegetables/bukkits/posts", last_response.body
end
test "isolated engine can be mounted under multiple dynamic locations" do
app_file "app/controllers/foos_controller.rb", <<-RUBY
class FoosController < ApplicationController
def through_fruits
render plain: fruit_bukkits.posts_path(fruit_id: 1)
end
def through_vegetables
render plain: vegetable_bukkits.posts_path(vegetable_id: 1)
end
end
RUBY
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
resources :fruits do
mount Bukkits::Engine => "/bukkits"
end
resources :vegetables do
mount Bukkits::Engine => "/bukkits"
end
get "/through_fruits" => "foos#through_fruits"
get "/through_vegetables" => "foos#through_vegetables"
end
RUBY
@plugin.write "config/routes.rb", <<-RUBY
Bukkits::Engine.routes.draw do
resources :posts, only: :index
end
RUBY
boot_rails
get("/through_fruits")
assert_equal "/fruits/1/bukkits/posts", last_response.body
get("/through_vegetables")
assert_equal "/vegetables/1/bukkits/posts", 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.
先完成此消息的编辑!
想要评论请 注册