From 6ed9ae5b317db4e3c38e45c02862cea724e9a23a Mon Sep 17 00:00:00 2001 From: Andrew White Date: Wed, 11 Dec 2024 15:23:00 +0000 Subject: [PATCH] Fix race condition in petition statistics creation --- app/models/petition.rb | 2 ++ spec/models/petition_spec.rb | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/app/models/petition.rb b/app/models/petition.rb index 82de660e7..211fac78a 100644 --- a/app/models/petition.rb +++ b/app/models/petition.rb @@ -510,6 +510,8 @@ def scheduled_debate_state def statistics super || create_statistics! + rescue ActiveRecord::RecordNotUnique => e + reload_statistics end def reset_signature_count!(time = Time.current) diff --git a/spec/models/petition_spec.rb b/spec/models/petition_spec.rb index a6c172c01..deb8b931e 100644 --- a/spec/models/petition_spec.rb +++ b/spec/models/petition_spec.rb @@ -4071,4 +4071,27 @@ end end end + + describe "#statistics" do + let(:petition) { FactoryBot.create(:open_petition) } + + it "creates a new statistics record if one doesn't exist" do + expect { + expect(petition.statistics).to be_an_instance_of(Petition::Statistics) + }.to change(Petition::Statistics, :count).by(1) + end + + it "doesn't raise an ActiveRecord::RecordNotUnique error" do + expect { + p1 = described_class.find(petition.id) + p2 = described_class.find(petition.id) + + expect(p1.association(:statistics).reader).to be_nil + expect(p1.association(:statistics)).to be_loaded + + expect(p2.statistics).to be_an_instance_of(Petition::Statistics) + expect(p1.statistics).to eq(p2.statistics) + }.not_to raise_error + end + end end