Skip to content

Commit 029a603

Browse files
authored
Merge pull request rails#46406 from fatkodima/insert_all-sti
Fix `insert_all`/`upsert_all` to handle STI
2 parents af09d6b + 5b91169 commit 029a603

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

activerecord/lib/active_record/insert_all.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class InsertAll # :nodoc:
88
attr_reader :on_duplicate, :update_only, :returning, :unique_by, :update_sql
99

1010
def initialize(model, inserts, on_duplicate:, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil)
11-
@model, @connection, @inserts = model, model.connection, inserts
11+
@model, @connection, @inserts = model, model.connection, inserts.map(&:stringify_keys)
1212
@on_duplicate, @update_only, @returning, @unique_by = on_duplicate, update_only, returning, unique_by
1313
@record_timestamps = record_timestamps.nil? ? model.record_timestamps : record_timestamps
1414

@@ -18,8 +18,9 @@ def initialize(model, inserts, on_duplicate:, update_only: nil, returning: nil,
1818
if @inserts.empty?
1919
@keys = []
2020
else
21+
resolve_sti
2122
resolve_attribute_aliases
22-
@keys = @inserts.first.keys.map(&:to_s)
23+
@keys = @inserts.first.keys
2324
end
2425

2526
configure_on_duplicate_update_logic
@@ -99,6 +100,15 @@ def has_attribute_aliases?(attributes)
99100
attributes.keys.any? { |attribute| model.attribute_alias?(attribute) }
100101
end
101102

103+
def resolve_sti
104+
return if model.descends_from_active_record?
105+
106+
sti_type = model.sti_name
107+
@inserts = @inserts.map do |insert|
108+
insert.reverse_merge(model.inheritance_column.to_s => sti_type)
109+
end
110+
end
111+
102112
def resolve_attribute_aliases
103113
return unless has_attribute_aliases?(@inserts.first)
104114

activerecord/test/cases/insert_all_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require "cases/helper"
44
require "models/author"
55
require "models/book"
6+
require "models/category"
67
require "models/cart"
78
require "models/developer"
89
require "models/ship"
@@ -282,6 +283,26 @@ def test_insert_all_and_upsert_all_with_aliased_attributes
282283
end
283284
end
284285

286+
def test_insert_all_and_upsert_all_with_sti
287+
assert_difference -> { Category.count }, 2 do
288+
SpecialCategory.insert_all [{ name: "First" }, { name: "Second", type: nil }]
289+
end
290+
291+
first, second = Category.last(2)
292+
assert_equal "SpecialCategory", first.type
293+
assert_nil second.type
294+
295+
if supports_insert_on_duplicate_update?
296+
SpecialCategory.upsert_all [{ id: 103, name: "First" }, { id: 104, name: "Second", type: nil }]
297+
298+
category3 = Category.find(103)
299+
assert_equal "SpecialCategory", category3.type
300+
301+
category4 = Category.find(104)
302+
assert_nil category4.type
303+
end
304+
end
305+
285306
def test_upsert_logs_message_including_model_name
286307
skip unless supports_insert_on_duplicate_update?
287308

0 commit comments

Comments
 (0)