Commit a7fda000 authored by Mikołaj Wawrzyniak's avatar Mikołaj Wawrzyniak

Merge branch '341839_dont_update_created_at_attributes_by_upsert_queries' into 'master'

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

See merge request gitlab-org/gitlab!71399
parents 03640b93 21d7ee36
......@@ -51,6 +51,12 @@ module BulkInsertSafe
PrimaryKeySetError = Class.new(StandardError)
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)
unless _bulk_insert_callback_allowed?(name, args)
raise MethodNotAllowedError,
......@@ -153,7 +159,7 @@ module BulkInsertSafe
item_batch, validate, &handle_attributes)
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
.pluck(primary_key)
end
......
......@@ -17,6 +17,7 @@ RSpec.describe BulkInsertSafe do
t.binary :sha_value, null: false, limit: 20
t.jsonb :jsonb_value, null: false
t.belongs_to :bulk_insert_parent_item, foreign_key: true, null: true
t.timestamps null: true
t.index :name, unique: true
end
......@@ -228,10 +229,20 @@ RSpec.describe BulkInsertSafe do
end
describe '.bulk_upsert!' do
subject(:bulk_upsert) { bulk_insert_item_class.bulk_upsert!([new_object], unique_by: %w[name]) }
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
......@@ -250,7 +261,7 @@ RSpec.describe BulkInsertSafe do
it 'successfully inserts an item' do
expect(ActiveRecord::InsertAll).to receive(:new)
.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
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