mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix polymorphic eager load with foreign_key as String.
The foreign_key could be `String` and just doing `owners_map[owner_key]` could return `nil`. To prevent this bug, we should `to_s` both keys if their types are different. Fixes #14734.
This commit is contained in:
parent
b17f6e6877
commit
4debc86bd3
5 changed files with 42 additions and 2 deletions
|
@ -1,3 +1,9 @@
|
|||
* Fixed polymorphic eager loading when using a String as foreign key.
|
||||
|
||||
Fixes #14734.
|
||||
|
||||
*Lauro Caetano*
|
||||
|
||||
* Changed scoped blocks to be executed with `instance_eval`
|
||||
|
||||
Named scopes (i.e. using STI) were previously cached according to
|
||||
|
|
|
@ -58,7 +58,11 @@ module ActiveRecord
|
|||
|
||||
def owners_by_key
|
||||
@owners_by_key ||= owners.group_by do |owner|
|
||||
owner[owner_key_name]
|
||||
if owner_key_type == association_key_type
|
||||
owner[owner_key_name]
|
||||
else
|
||||
owner[owner_key_name].to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -93,13 +97,24 @@ module ActiveRecord
|
|||
records_by_owner
|
||||
end
|
||||
|
||||
def association_key_type
|
||||
@klass.column_types[association_key_name.to_s].type
|
||||
end
|
||||
|
||||
def owner_key_type
|
||||
@model.column_types[owner_key_name.to_s].type
|
||||
end
|
||||
|
||||
def load_slices(slices)
|
||||
@preloaded_records = slices.flat_map { |slice|
|
||||
records_for(slice)
|
||||
}
|
||||
|
||||
@preloaded_records.map { |record|
|
||||
[record, record[association_key_name]]
|
||||
key = record[association_key_name]
|
||||
key = key.to_s unless owner_key_type == association_key_type
|
||||
|
||||
[record, key]
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -570,6 +570,19 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|||
assert companies(:first_client).readonly_firm.readonly?
|
||||
end
|
||||
|
||||
def test_test_polymorphic_assignment_foreign_key_type_string
|
||||
comment = Comment.first
|
||||
comment.author = Author.first
|
||||
comment.resource = Member.first
|
||||
comment.save
|
||||
|
||||
assert_equal Comment.all.to_a,
|
||||
Comment.includes(:author).to_a
|
||||
|
||||
assert_equal Comment.all.to_a,
|
||||
Comment.includes(:resource).to_a
|
||||
end
|
||||
|
||||
def test_polymorphic_assignment_foreign_type_field_updating
|
||||
# should update when assigning a saved record
|
||||
sponsor = Sponsor.new
|
||||
|
|
|
@ -7,6 +7,9 @@ class Comment < ActiveRecord::Base
|
|||
scope :created, -> { all }
|
||||
|
||||
belongs_to :post, :counter_cache => true
|
||||
belongs_to :author, polymorphic: true
|
||||
belongs_to :resource, polymorphic: true
|
||||
|
||||
has_many :ratings
|
||||
|
||||
belongs_to :first_post, :foreign_key => :post_id
|
||||
|
|
|
@ -187,6 +187,9 @@ ActiveRecord::Schema.define do
|
|||
t.integer :taggings_count, default: 0
|
||||
t.integer :children_count, default: 0
|
||||
t.integer :parent_id
|
||||
t.references :author, polymorphic: true
|
||||
t.string :resource_id
|
||||
t.string :resource_type
|
||||
end
|
||||
|
||||
create_table :companies, force: true do |t|
|
||||
|
|
Loading…
Reference in a new issue