Skip to content

Commit 2ce81b0

Browse files
committed
[Fix #51720] Infer association klass as top level if model has same demodularized name
1 parent 793ff00 commit 2ce81b0

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

activerecord/lib/active_record/reflection.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,21 @@ def autosave=(autosave)
422422
# a new association object. Use +build_association+ or +create_association+
423423
# instead. This allows plugins to hook into association object creation.
424424
def klass
425-
@klass ||= compute_class(class_name)
425+
@klass ||= compute_class(compute_name(class_name))
426426
end
427427

428428
def compute_class(name)
429429
name.constantize
430430
end
431431

432+
def compute_name(name) # :nodoc:
433+
if active_record.name['::'] && active_record.name.demodulize == name
434+
"::#{name}"
435+
else
436+
name
437+
end
438+
end
439+
432440
# Returns +true+ if +self+ and +other_aggregation+ have the same +name+ attribute, +active_record+ attribute,
433441
# and +other_aggregation+ has an options hash assigned to it.
434442
def ==(other_aggregation)
@@ -979,7 +987,7 @@ def through_reflection?
979987
end
980988

981989
def klass
982-
@klass ||= delegate_reflection.compute_class(class_name)
990+
@klass ||= delegate_reflection.compute_class(compute_name(class_name))
983991
end
984992

985993
# Returns the source of the through reflection. It checks both a singularized

activerecord/test/cases/reflection_test.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
require "models/user_with_invalid_relation"
3131
require "models/hardback"
3232
require "models/sharded/comment"
33+
require "models/admin"
34+
require "models/admin/user"
35+
require "models/user"
3336

3437
class ReflectionTest < ActiveRecord::TestCase
3538
include ActiveRecord::Reflection
@@ -181,6 +184,18 @@ def test_reflection_klass_requires_ar_subclass
181184
end
182185
end
183186

187+
def test_reflection_klass_with_same_demodularized_name
188+
reflection = ActiveRecord::Reflection.create(
189+
:has_one,
190+
:user,
191+
nil,
192+
{},
193+
Admin::User
194+
)
195+
196+
assert_equal User, reflection.klass
197+
end
198+
184199
def test_aggregation_reflection
185200
reflection_for_address = AggregateReflection.new(
186201
:address, nil, { mapping: [ %w(address_street street), %w(address_city city), %w(address_country country) ] }, Customer

0 commit comments

Comments
 (0)