Commit 21d7ee36 authored by Mehmet Emin INAC's avatar Mehmet Emin INAC

Mark the `created_at` attribute as read-only to prevent updating it

This is necessary to prevent updating the `created_at` values by UPSERT
queries.

Changelog: fixed
parent f10ed003
...@@ -51,6 +51,12 @@ module BulkInsertSafe ...@@ -51,6 +51,12 @@ module BulkInsertSafe
PrimaryKeySetError = Class.new(StandardError) PrimaryKeySetError = Class.new(StandardError)
class_methods do class_methods do
def insert_all_proxy_class
@insert_all_proxy_class ||= Class.new(self) do
attr_readonly :created_at
end
end
def set_callback(name, *args) def set_callback(name, *args)
unless _bulk_insert_callback_allowed?(name, args) unless _bulk_insert_callback_allowed?(name, args)
raise MethodNotAllowedError, raise MethodNotAllowedError,
...@@ -153,7 +159,7 @@ module BulkInsertSafe ...@@ -153,7 +159,7 @@ module BulkInsertSafe
item_batch, validate, &handle_attributes) item_batch, validate, &handle_attributes)
ActiveRecord::InsertAll ActiveRecord::InsertAll
.new(self, attributes, on_duplicate: on_duplicate, returning: returning, unique_by: unique_by) .new(insert_all_proxy_class, attributes, on_duplicate: on_duplicate, returning: returning, unique_by: unique_by)
.execute .execute
.pluck(primary_key) .pluck(primary_key)
end end
......
...@@ -17,6 +17,7 @@ RSpec.describe BulkInsertSafe do ...@@ -17,6 +17,7 @@ RSpec.describe BulkInsertSafe do
t.binary :sha_value, null: false, limit: 20 t.binary :sha_value, null: false, limit: 20
t.jsonb :jsonb_value, null: false t.jsonb :jsonb_value, null: false
t.belongs_to :bulk_insert_parent_item, foreign_key: true, null: true t.belongs_to :bulk_insert_parent_item, foreign_key: true, null: true
t.timestamps null: true
t.index :name, unique: true t.index :name, unique: true
end end
...@@ -228,10 +229,20 @@ RSpec.describe BulkInsertSafe do ...@@ -228,10 +229,20 @@ RSpec.describe BulkInsertSafe do
end end
describe '.bulk_upsert!' do describe '.bulk_upsert!' do
subject(:bulk_upsert) { bulk_insert_item_class.bulk_upsert!([new_object], unique_by: %w[name]) }
it 'updates existing object' do it 'updates existing object' do
bulk_insert_item_class.bulk_upsert!([new_object], unique_by: %w[name]) expect { bulk_upsert }.to change { existing_object.reload.secret_value }.to('new value')
end
expect(existing_object.reload.secret_value).to eq('new value') context 'when the `created_at` attribute is provided' do
before do
new_object.created_at = 10.days.from_now
end
it 'does not change the existing `created_at` value' do
expect { bulk_upsert }.not_to change { existing_object.reload.created_at }
end
end end
end end
end end
...@@ -250,7 +261,7 @@ RSpec.describe BulkInsertSafe do ...@@ -250,7 +261,7 @@ RSpec.describe BulkInsertSafe do
it 'successfully inserts an item' do it 'successfully inserts an item' do
expect(ActiveRecord::InsertAll).to receive(:new) expect(ActiveRecord::InsertAll).to receive(:new)
.with( .with(
bulk_insert_items_with_composite_pk_class, [new_object.as_json], on_duplicate: :raise, returning: false, unique_by: %w[id name] bulk_insert_items_with_composite_pk_class.insert_all_proxy_class, [new_object.as_json], on_duplicate: :raise, returning: false, unique_by: %w[id name]
).and_call_original ).and_call_original
expect { bulk_insert_items_with_composite_pk_class.bulk_insert!([new_object]) }.to( expect { bulk_insert_items_with_composite_pk_class.bulk_insert!([new_object]) }.to(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment