Skip to content

Commit

Permalink
[Fix rails#51720] Infer association klass as top level if model has s…
Browse files Browse the repository at this point in the history
…ame demodularized name
  • Loading branch information
joshuay03 committed May 3, 2024
1 parent 793ff00 commit 2ce81b0
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
12 changes: 10 additions & 2 deletions activerecord/lib/active_record/reflection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -422,13 +422,21 @@ def autosave=(autosave)
# a new association object. Use +build_association+ or +create_association+
# instead. This allows plugins to hook into association object creation.
def klass
@klass ||= compute_class(class_name)
@klass ||= compute_class(compute_name(class_name))
end

def compute_class(name)
name.constantize
end

def compute_name(name) # :nodoc:
if active_record.name['::'] && active_record.name.demodulize == name
"::#{name}"
else
name
end
end

# Returns +true+ if +self+ and +other_aggregation+ have the same +name+ attribute, +active_record+ attribute,
# and +other_aggregation+ has an options hash assigned to it.
def ==(other_aggregation)
Expand Down Expand Up @@ -979,7 +987,7 @@ def through_reflection?
end

def klass
@klass ||= delegate_reflection.compute_class(class_name)
@klass ||= delegate_reflection.compute_class(compute_name(class_name))
end

# Returns the source of the through reflection. It checks both a singularized
Expand Down
15 changes: 15 additions & 0 deletions activerecord/test/cases/reflection_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
require "models/user_with_invalid_relation"
require "models/hardback"
require "models/sharded/comment"
require "models/admin"
require "models/admin/user"
require "models/user"

class ReflectionTest < ActiveRecord::TestCase
include ActiveRecord::Reflection
Expand Down Expand Up @@ -181,6 +184,18 @@ def test_reflection_klass_requires_ar_subclass
end
end

def test_reflection_klass_with_same_demodularized_name
reflection = ActiveRecord::Reflection.create(
:has_one,
:user,
nil,
{},
Admin::User
)

assert_equal User, reflection.klass
end

def test_aggregation_reflection
reflection_for_address = AggregateReflection.new(
:address, nil, { mapping: [ %w(address_street street), %w(address_city city), %w(address_country country) ] }, Customer
Expand Down

0 comments on commit 2ce81b0

Please sign in to comment.