2019-03-05 14:16:44 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require "cases/helper"
|
|
|
|
require "models/book"
|
|
|
|
|
|
|
|
class ReadonlyNameBook < Book
|
|
|
|
attr_readonly :name
|
|
|
|
end
|
|
|
|
|
2019-03-06 10:20:44 -05:00
|
|
|
class InsertAllTest < ActiveRecord::TestCase
|
2019-03-05 14:16:44 -05:00
|
|
|
fixtures :books
|
|
|
|
|
|
|
|
def test_insert
|
2019-03-31 14:41:18 -04:00
|
|
|
skip unless supports_insert_on_duplicate_skip?
|
|
|
|
|
|
|
|
id = 1_000_000
|
|
|
|
|
|
|
|
assert_difference "Book.count", +1 do
|
|
|
|
Book.insert(id: id, name: "Rework", author_id: 1)
|
|
|
|
end
|
|
|
|
|
|
|
|
Book.upsert(id: id, name: "Remote", author_id: 1)
|
|
|
|
|
|
|
|
assert_equal "Remote", Book.find(id).name
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert!
|
2019-03-05 14:16:44 -05:00
|
|
|
assert_difference "Book.count", +1 do
|
|
|
|
Book.insert! name: "Rework", author_id: 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert_all
|
|
|
|
assert_difference "Book.count", +10 do
|
|
|
|
Book.insert_all! [
|
|
|
|
{ name: "Rework", author_id: 1 },
|
|
|
|
{ name: "Patterns of Enterprise Application Architecture", author_id: 1 },
|
|
|
|
{ name: "Design of Everyday Things", author_id: 1 },
|
|
|
|
{ name: "Practical Object-Oriented Design in Ruby", author_id: 1 },
|
|
|
|
{ name: "Clean Code", author_id: 1 },
|
|
|
|
{ name: "Ruby Under a Microscope", author_id: 1 },
|
|
|
|
{ name: "The Principles of Product Development Flow", author_id: 1 },
|
|
|
|
{ name: "Peopleware", author_id: 1 },
|
|
|
|
{ name: "About Face", author_id: 1 },
|
|
|
|
{ name: "Eloquent Ruby", author_id: 1 },
|
|
|
|
]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert_all_should_handle_empty_arrays
|
2019-03-06 10:19:53 -05:00
|
|
|
assert_raise ArgumentError do
|
2019-03-05 14:16:44 -05:00
|
|
|
Book.insert_all! []
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert_all_raises_on_duplicate_records
|
|
|
|
assert_raise ActiveRecord::RecordNotUnique do
|
|
|
|
Book.insert_all! [
|
|
|
|
{ name: "Rework", author_id: 1 },
|
|
|
|
{ name: "Patterns of Enterprise Application Architecture", author_id: 1 },
|
|
|
|
{ name: "Agile Web Development with Rails", author_id: 1 },
|
|
|
|
]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert_all_returns_ActiveRecord_Result
|
|
|
|
result = Book.insert_all! [{ name: "Rework", author_id: 1 }]
|
|
|
|
assert_kind_of ActiveRecord::Result, result
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert_all_returns_primary_key_if_returning_is_supported
|
|
|
|
skip unless supports_insert_returning?
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
result = Book.insert_all! [{ name: "Rework", author_id: 1 }]
|
|
|
|
assert_equal %w[ id ], result.columns
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert_all_returns_nothing_if_returning_is_empty
|
|
|
|
skip unless supports_insert_returning?
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
result = Book.insert_all! [{ name: "Rework", author_id: 1 }], returning: []
|
|
|
|
assert_equal [], result.columns
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert_all_returns_nothing_if_returning_is_false
|
|
|
|
skip unless supports_insert_returning?
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
result = Book.insert_all! [{ name: "Rework", author_id: 1 }], returning: false
|
|
|
|
assert_equal [], result.columns
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert_all_returns_requested_fields
|
|
|
|
skip unless supports_insert_returning?
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
result = Book.insert_all! [{ name: "Rework", author_id: 1 }], returning: [:id, :name]
|
|
|
|
assert_equal %w[ Rework ], result.pluck("name")
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert_all_can_skip_duplicate_records
|
|
|
|
skip unless supports_insert_on_duplicate_skip?
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
assert_no_difference "Book.count" do
|
|
|
|
Book.insert_all [{ id: 1, name: "Agile Web Development with Rails" }]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_insert_all_will_raise_if_duplicates_are_skipped_only_for_a_certain_conflict_target
|
|
|
|
skip unless supports_insert_on_duplicate_skip? && supports_insert_conflict_target?
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
assert_raise ActiveRecord::RecordNotUnique do
|
|
|
|
Book.insert_all [{ id: 1, name: "Agile Web Development with Rails" }],
|
2019-03-08 19:15:17 -05:00
|
|
|
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
|
2019-03-05 14:16:44 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_upsert_all_updates_existing_records
|
|
|
|
skip unless supports_insert_on_duplicate_update?
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
new_name = "Agile Web Development with Rails, 4th Edition"
|
|
|
|
Book.upsert_all [{ id: 1, name: new_name }]
|
|
|
|
assert_equal new_name, Book.find(1).name
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_upsert_all_does_not_update_readonly_attributes
|
|
|
|
skip unless supports_insert_on_duplicate_update?
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
new_name = "Agile Web Development with Rails, 4th Edition"
|
|
|
|
ReadonlyNameBook.upsert_all [{ id: 1, name: new_name }]
|
|
|
|
assert_not_equal new_name, Book.find(1).name
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_upsert_all_does_not_update_primary_keys
|
|
|
|
skip unless supports_insert_on_duplicate_update? && supports_insert_conflict_target?
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
Book.upsert_all [{ id: 101, name: "Perelandra", author_id: 7 }]
|
|
|
|
Book.upsert_all [{ id: 103, name: "Perelandra", author_id: 7, isbn: "1974522598" }],
|
2019-03-08 19:15:17 -05:00
|
|
|
unique_by: :index_books_on_author_id_and_name
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
book = Book.find_by(name: "Perelandra")
|
|
|
|
assert_equal 101, book.id, "Should not have updated the ID"
|
|
|
|
assert_equal "1974522598", book.isbn, "Should have updated the isbn"
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_upsert_all_does_not_perform_an_upsert_if_a_partial_index_doesnt_apply
|
|
|
|
skip unless supports_insert_on_duplicate_update? && supports_insert_conflict_target? && supports_partial_index?
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
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" }],
|
2019-03-08 19:15:17 -05:00
|
|
|
unique_by: :index_books_on_isbn
|
2019-03-06 10:29:22 -05:00
|
|
|
|
2019-03-05 14:16:44 -05:00
|
|
|
assert_equal ["Out of the Silent Planet", "Perelandra"], Book.where(isbn: "1974522598").order(:name).pluck(:name)
|
|
|
|
end
|
2019-03-15 22:33:48 -04:00
|
|
|
|
|
|
|
def test_insert_all_raises_on_unknown_attribute
|
|
|
|
assert_raise ActiveRecord::UnknownAttributeError do
|
|
|
|
Book.insert_all! [{ unknown_attribute: "Test" }]
|
|
|
|
end
|
|
|
|
end
|
2019-03-05 14:16:44 -05:00
|
|
|
end
|