diff options
author | Kasper Timm Hansen <kaspth@gmail.com> | 2019-03-09 01:15:17 +0100 |
---|---|---|
committer | Kasper Timm Hansen <kaspth@gmail.com> | 2019-03-20 13:28:18 +0100 |
commit | 2ea5c24085e39efb6c1bc6e7062bcc5f496d1fa6 (patch) | |
tree | 9a6448dca6dcd973957584686edf60961189ae01 /activerecord/test/cases | |
parent | c11d115fa3c58ec6bde5e9799673cee381d22d47 (diff) | |
download | rails-2ea5c24085e39efb6c1bc6e7062bcc5f496d1fa6.tar.gz rails-2ea5c24085e39efb6c1bc6e7062bcc5f496d1fa6.tar.bz2 rails-2ea5c24085e39efb6c1bc6e7062bcc5f496d1fa6.zip |
Bulk Insert: Reuse indexes for unique_by
I found `:unique_by` with `:columns` and `:where` inside it tough to
grasp. The documentation only mentioned indexes and partial indexes.
So why duplicate a model's indexes in an insert_all/upsert_all call
when we can just look it up?
This has the added benefit of raising if no index is found, such that
people can't insert thousands of records without relying on an index
of some form.
Diffstat (limited to 'activerecord/test/cases')
-rw-r--r-- | activerecord/test/cases/insert_all_test.rb | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/activerecord/test/cases/insert_all_test.rb b/activerecord/test/cases/insert_all_test.rb index a3e920969d..0818d7c1ab 100644 --- a/activerecord/test/cases/insert_all_test.rb +++ b/activerecord/test/cases/insert_all_test.rb @@ -95,7 +95,37 @@ class InsertAllTest < ActiveRecord::TestCase assert_raise ActiveRecord::RecordNotUnique do Book.insert_all [{ id: 1, name: "Agile Web Development with Rails" }], - unique_by: { columns: %i{author_id name} } + unique_by: :index_books_on_author_id_and_name + end + end + + def test_insert_all_and_upsert_all_with_index_finding_options + skip unless supports_insert_conflict_target? + + assert_difference "Book.count", +3 do + Book.insert_all [{ name: "Rework", author_id: 1 }], unique_by: :isbn + Book.insert_all [{ name: "Remote", author_id: 1 }], unique_by: %i( author_id name ) + Book.insert_all [{ name: "Renote", author_id: 1 }], unique_by: :index_books_on_isbn + end + + assert_raise ActiveRecord::RecordNotUnique do + Book.upsert_all [{ name: "Rework", author_id: 1 }], unique_by: :isbn + end + end + + def test_insert_all_and_upsert_all_raises_when_index_is_missing + skip unless supports_insert_conflict_target? + + [ :cats, %i( author_id isbn ), :author_id ].each do |missing_or_non_unique_by| + error = assert_raises ArgumentError do + Book.insert_all [{ name: "Rework", author_id: 1 }], unique_by: missing_or_non_unique_by + end + assert_match "No unique index", error.message + + error = assert_raises ArgumentError do + Book.upsert_all [{ name: "Rework", author_id: 1 }], unique_by: missing_or_non_unique_by + end + assert_match "No unique index", error.message end end @@ -120,7 +150,7 @@ class InsertAllTest < ActiveRecord::TestCase Book.upsert_all [{ id: 101, name: "Perelandra", author_id: 7 }] Book.upsert_all [{ id: 103, name: "Perelandra", author_id: 7, isbn: "1974522598" }], - unique_by: { columns: %i{author_id name} } + unique_by: :index_books_on_author_id_and_name book = Book.find_by(name: "Perelandra") assert_equal 101, book.id, "Should not have updated the ID" @@ -132,7 +162,7 @@ class InsertAllTest < ActiveRecord::TestCase Book.upsert_all [{ name: "Out of the Silent Planet", author_id: 7, isbn: "1974522598", published_on: Date.new(1938, 4, 1) }] Book.upsert_all [{ name: "Perelandra", author_id: 7, isbn: "1974522598" }], - unique_by: { columns: %w[ isbn ], where: "published_on IS NOT NULL" } + unique_by: :index_books_on_isbn assert_equal ["Out of the Silent Planet", "Perelandra"], Book.where(isbn: "1974522598").order(:name).pluck(:name) end |