aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLachlan Sylvester <lachlan.sylvester@hypothetical.com.au>2019-06-21 15:34:45 +1000
committerKasper Timm Hansen <kaspth@gmail.com>2019-08-05 02:39:52 +0200
commit1af44e4aeeb04a6360b5104d8ee7b4a042ef93d8 (patch)
tree289ff122e1fd2b6531b065c77fb8cf7b4e0e5dd0
parent6c6d852854ad068acf7d610808ed501b7d13c7f6 (diff)
downloadrails-1af44e4aeeb04a6360b5104d8ee7b4a042ef93d8.tar.gz
rails-1af44e4aeeb04a6360b5104d8ee7b4a042ef93d8.tar.bz2
rails-1af44e4aeeb04a6360b5104d8ee7b4a042ef93d8.zip
handle passing in primary key to unique_by, and handle primary keys missing indexes
-rw-r--r--activerecord/lib/active_record/insert_all.rb6
-rw-r--r--activerecord/test/cases/insert_all_test.rb18
2 files changed, 22 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/insert_all.rb b/activerecord/lib/active_record/insert_all.rb
index f6577dcbc4..3863b6bfea 100644
--- a/activerecord/lib/active_record/insert_all.rb
+++ b/activerecord/lib/active_record/insert_all.rb
@@ -14,7 +14,7 @@ module ActiveRecord
@returning = (connection.supports_insert_returning? ? primary_keys : false) if @returning.nil?
@returning = false if @returning == []
- @unique_by = find_unique_index_for(unique_by) if unique_by
+ @unique_by = find_unique_index_for(unique_by || model.primary_key)
@on_duplicate = :skip if @on_duplicate == :update && updatable_columns.empty?
ensure_valid_options_for_connection!
@@ -32,7 +32,7 @@ module ActiveRecord
end
def primary_keys
- Array(model.primary_key)
+ Array(connection.schema_cache.primary_keys(model.table_name))
end
@@ -61,6 +61,8 @@ module ActiveRecord
if index = unique_indexes.find { |i| match.include?(i.name) || i.columns == match }
index
+ elsif match == primary_keys
+ nil
else
raise ArgumentError, "No unique index found for #{unique_by}"
end
diff --git a/activerecord/test/cases/insert_all_test.rb b/activerecord/test/cases/insert_all_test.rb
index d086d77081..42c623fafb 100644
--- a/activerecord/test/cases/insert_all_test.rb
+++ b/activerecord/test/cases/insert_all_test.rb
@@ -2,6 +2,7 @@
require "cases/helper"
require "models/book"
+require "models/speedometer"
class ReadonlyNameBook < Book
attr_readonly :name
@@ -225,6 +226,23 @@ class InsertAllTest < ActiveRecord::TestCase
assert_equal new_name, Book.find(1).name
end
+ def test_upsert_all_updates_existing_record_by_primary_key
+ skip unless supports_insert_on_duplicate_update?
+
+ Book.upsert_all [{ id: 1, name: "New edition" }], unique_by: :id
+
+ assert_equal "New edition", Book.find(1).name
+ end
+
+ def test_upsert_all_updates_existing_record_by_configured_primary_key
+ skip unless supports_insert_on_duplicate_update?
+
+ error = assert_raises ArgumentError do
+ Speedometer.upsert_all [{ speedometer_id: "s1", name: "New Speedometer" }]
+ end
+ assert_match "No unique index found for speedometer_id", error.message
+ end
+
def test_upsert_all_does_not_update_readonly_attributes
skip unless supports_insert_on_duplicate_update?