Force _routes to be redefined on re-inclusion

This fixes an regression where _routes were set incorrectly when the
inheritance chain went from one route namespace (isolated engine or main
app) to another and then back to the original. Because the url_helpers
module was being cached and was being re-included this was not setting
_routes.

This commit solves the issue by detecting that case and redefining
_routes in that case. We could have always performed the redefinition,
but it's a pretty uncommon case, so we might as well only do it when
necessary.
This commit is contained in:
John Hawthorn 2021-02-16 10:10:25 -08:00
parent d79f3b2a37
commit d6ca73306c
1 changed files with 17 additions and 1 deletions

View File

@ -7,11 +7,27 @@ module AbstractController
Module.new do Module.new do
define_method(:inherited) do |klass| define_method(:inherited) do |klass|
super(klass) super(klass)
if namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
actual_routes = namespace ? namespace.railtie_routes_url_helpers._routes : routes
if namespace
klass.include(namespace.railtie_routes_url_helpers(include_path_helpers)) klass.include(namespace.railtie_routes_url_helpers(include_path_helpers))
else else
klass.include(routes.url_helpers(include_path_helpers)) klass.include(routes.url_helpers(include_path_helpers))
end end
# In the case that we have ex.
# class A::Foo < ApplicationController
# class Bar < A::Foo
# We will need to redefine _routes because it will not be correct
# via inheritance.
unless klass._routes.equal?(actual_routes)
klass.redefine_singleton_method(:_routes) { actual_routes }
klass.include(Module.new do
define_method(:_routes) { @_routes || actual_routes }
end)
end
end end
end end
end end