From 67f19c22ea3707a2a129a1b5ae978efa71883a5f Mon Sep 17 00:00:00 2001 From: Heinrich Lee Yu Date: Tue, 21 Oct 2025 13:14:01 +0800 Subject: [PATCH] Fix bulk insert of vulnerability reads in Rails 7.2 The `Vulnerabilities::Read` model has `vulnerability_id` as the primary key but it also has an `id` column. Rails treats `id` as a special attribute and reading / writing `id` actually writes to the primary key. We need to remove `id` from the attributes hash so that the value can be auto-generated from the sequence. --- ee/app/models/vulnerabilities/read.rb | 1 + ee/app/services/vulnerabilities/reads/upsert_service.rb | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ee/app/models/vulnerabilities/read.rb b/ee/app/models/vulnerabilities/read.rb index 2cac5e118730dd..b80c8bbd27f19f 100644 --- a/ee/app/models/vulnerabilities/read.rb +++ b/ee/app/models/vulnerabilities/read.rb @@ -62,6 +62,7 @@ class Read < ::SecApplicationRecord scope :by_uuid, ->(uuids) { where(uuid: uuids) } scope :by_vulnerabilities, ->(vulnerabilities) { where(vulnerability: vulnerabilities) } + scope :excluding_vulnerabilities, ->(vulnerabilities) { where.not(vulnerability: vulnerabilities) } class << self alias_method :by_vulnerability, :by_vulnerabilities diff --git a/ee/app/services/vulnerabilities/reads/upsert_service.rb b/ee/app/services/vulnerabilities/reads/upsert_service.rb index 7a36f8d5d6aff4..65025eded01be6 100644 --- a/ee/app/services/vulnerabilities/reads/upsert_service.rb +++ b/ee/app/services/vulnerabilities/reads/upsert_service.rb @@ -45,7 +45,7 @@ def execute next unless attributes.any? vulnerability_read_batch = Vulnerabilities::Read.by_vulnerabilities(vulnerability_batch) - .id_not_in(new_read_ids) + .excluding_vulnerabilities(new_read_ids) vulnerability_read_batch.update_all(attributes) @@ -118,8 +118,10 @@ def perform_bulk_insert(vulnerability_reads_for_insert) ::Vulnerabilities::Read.bulk_upsert!( vulnerability_reads_for_insert, unique_by: %i[uuid], - returns: :ids - ) + returns: [:vulnerability_id] + ) do |item_attrs| + item_attrs.delete('id') # `id` is an auto-generated sequence + end end def build_vulnerability_read(vulnerability) -- GitLab