Skip to content

Commit

Permalink
Model.insert_all can accept an array of records with separate column …
Browse files Browse the repository at this point in the history
…names.
  • Loading branch information
robertomiranda committed Mar 12, 2024
1 parent 4d3e291 commit f41808c
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
11 changes: 9 additions & 2 deletions activerecord/lib/active_record/insert_all.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ def execute(model, ...)
end
end

def initialize(model, connection, inserts, on_duplicate:, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil)
@model, @connection, @inserts = model, connection, inserts.map(&:stringify_keys)
def initialize(model, connection, inserts, on_duplicate:, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil, column_names: nil)
@model, @connection, @inserts = model, connection

if column_names
@inserts = inserts.map { |values| column_names.map(&:to_s).zip(values).to_h }
else
@inserts = inserts.map(&:stringify_keys)
end

@on_duplicate, @update_only, @returning, @unique_by = on_duplicate, update_only, returning, unique_by
@record_timestamps = record_timestamps.nil? ? model.record_timestamps : record_timestamps

Expand Down
4 changes: 2 additions & 2 deletions activerecord/lib/active_record/persistence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ def insert(attributes, returning: nil, unique_by: nil, record_timestamps: nil)
# { id: 1, title: "Rework" },
# { id: 2, title: "Eloquent Ruby" }
# ])
def insert_all(attributes, returning: nil, unique_by: nil, record_timestamps: nil)
InsertAll.execute(self, attributes, on_duplicate: :skip, returning: returning, unique_by: unique_by, record_timestamps: record_timestamps)
def insert_all(attributes, returning: nil, unique_by: nil, record_timestamps: nil, column_names: nil)
InsertAll.execute(self, attributes, on_duplicate: :skip, returning: returning, unique_by: unique_by, record_timestamps: record_timestamps, column_names: column_names)
end

# Inserts a single record into the database in a single SQL INSERT
Expand Down
20 changes: 20 additions & 0 deletions activerecord/test/cases/insert_all_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,26 @@ def test_insert_all
end
end

def test_insert_all_with_column_names
assert_difference "Book.count", +10 do
column_names = [:name, :author_id]
books_data = [
["Rework", 1],
["Patterns of Enterprise Application Architecture", 1],
["Design of Everyday Things", 1],
["Practical Object-Oriented Design in Ruby", 1],
["Clean Code", 1],
["Ruby Under a Microscope", 1],
["The Principles of Product Development Flow", 1],
["Peopleware", 1],
["About Face", 1],
["Eloquent Ruby", 1]
]

Book.insert_all(books_data, column_names: column_names)
end
end

def test_insert_all_should_handle_empty_arrays
skip unless supports_insert_on_duplicate_update?

Expand Down

0 comments on commit f41808c

Please sign in to comment.