Skip to content

Commit f2d1b7b

Browse files
authored
Merge pull request rails#46530 from jonathanhefner/url_helpers-use-dup-for-reinclusion
Use memoized dup of `url_helpers` for reinclusion
2 parents a8efccc + 7bcca5b commit f2d1b7b

File tree

3 files changed

+19
-35
lines changed

3 files changed

+19
-35
lines changed

actionpack/lib/abstract_controller/railties/routes_helpers.rb

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,11 @@ def self.with(routes, include_path_helpers = true)
1010
define_method(:inherited) do |klass|
1111
super(klass)
1212

13-
namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
14-
actual_routes = namespace ? namespace.railtie_routes_url_helpers._routes : routes
15-
16-
if namespace
13+
if namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
1714
klass.include(namespace.railtie_routes_url_helpers(include_path_helpers))
1815
else
1916
klass.include(routes.url_helpers(include_path_helpers))
2017
end
21-
22-
# In the case that we have ex.
23-
# class A::Foo < ApplicationController
24-
# class Bar < A::Foo
25-
# We will need to redefine _routes because it will not be correct
26-
# via inheritance.
27-
unless klass._routes.equal?(actual_routes)
28-
klass.redefine_singleton_method(:_routes) { actual_routes }
29-
klass.include(Module.new do
30-
define_method(:_routes) { @_routes || actual_routes }
31-
end)
32-
end
3318
end
3419
end
3520
end

actionpack/lib/action_dispatch/routing/route_set.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,20 @@ def url_options; {}; end
574574
end
575575

576576
private :_generate_paths_by_default
577+
578+
# If the module is included more than once (for example, in a subclass
579+
# of an ancestor that includes the module), ensure that the `_routes`
580+
# singleton and instance methods return the desired route set by
581+
# including a new copy of the module (recursively if necessary). Note
582+
# that this method is called for each inclusion, whereas the above
583+
# `included` block is run only for the initial inclusion of each copy.
584+
def self.included(base)
585+
super
586+
if !base._routes.equal?(@_proxy._routes)
587+
@dup_for_reinclude ||= self.dup
588+
base.include @dup_for_reinclude
589+
end
590+
end
577591
end
578592
end
579593

actionpack/test/controller/route_helpers_test.rb

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,6 @@
33
require "abstract_unit"
44

55
class RouteHelperIntegrationTest < ActionDispatch::IntegrationTest
6-
def self.routes
7-
@routes ||= ActionDispatch::Routing::RouteSet.new
8-
end
9-
10-
class FakeACBase < ActionController::Base
11-
# Normally done by app initialization to ActionController::Base
12-
app = RouteHelperIntegrationTest
13-
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
14-
end
15-
16-
class ApplicationController < FakeACBase
17-
end
18-
196
class FooController < ApplicationController
207
end
218

@@ -24,18 +11,16 @@ class FooController < ApplicationController
2411
# duplicate these modules and make method cache invalidation expensive.
2512
# https://github.com/rails/rails/pull/37927
2613
test "only includes one module with route helpers" do
27-
app = self.class
28-
29-
url_helpers_module = app.routes.named_routes.url_helpers_module
30-
path_helpers_module = app.routes.named_routes.path_helpers_module
14+
url_helpers_module = SharedTestRoutes.named_routes.url_helpers_module
15+
path_helpers_module = SharedTestRoutes.named_routes.path_helpers_module
3116

3217
assert_operator FooController, :<, url_helpers_module
3318
assert_operator ApplicationController, :<, url_helpers_module
34-
assert_not_operator FakeACBase, :<, url_helpers_module
19+
assert_not_operator ActionController::Base, :<, url_helpers_module
3520

3621
assert_operator FooController, :<, path_helpers_module
3722
assert_operator ApplicationController, :<, path_helpers_module
38-
assert_not_operator FakeACBase, :<, path_helpers_module
23+
assert_not_operator ActionController::Base, :<, path_helpers_module
3924

4025
included_modules = FooController.ancestors.grep_v(Class)
4126
included_modules -= [url_helpers_module, path_helpers_module]

0 commit comments

Comments
 (0)