Fix inclusion of url_helpers module in concern

Follow-up to #46530.

The dynamically generated `url_helpers` module is an
`ActiveSupport::Concern`.  Therefore, when it is included directly in
another `ActiveSupport::Concern`, its `included` block is deferred until
the latter concern is itself included elsewhere.  Thus, in that case,
the call to `base._routes` in `def self.included(base)` will raise
`NoMethodError` because the `included` block will not yet have defined
the `_routes` method.

This commit prevents the error by first checking if `base` responds to
`_routes`.
This commit is contained in:
Jonathan Hefner 2023-12-19 17:43:32 -06:00
parent b0048c787a
commit 76c26135b9
2 changed files with 12 additions and 1 deletions

@ -604,7 +604,7 @@ def url_options; {}; end
# `included` block is run only for the initial inclusion of each copy.
def self.included(base)
super
if !base._routes.equal?(@_proxy._routes)
if base.respond_to?(:_routes) && !base._routes.equal?(@_proxy._routes)
@dup_for_reinclude ||= self.dup
base.include @dup_for_reinclude
end

@ -301,6 +301,17 @@ def test_resolve_urls
assert_equal "http://www.example.com/manufacturers/apple", Routes.url_helpers.polymorphic_url(@manufacturer)
end
def test_url_helpers_module_can_be_included_directly_in_an_active_support_concern
concern = Module.new do
extend ActiveSupport::Concern
include Routes.url_helpers
end
concerned = Class.new { include concern }.new
assert_equal "http://www.example.com/", concerned.root_url
end
def test_defining_direct_inside_a_scope_raises_runtime_error
routes = ActionDispatch::Routing::RouteSet.new