From 32d96d482dae8179ec8c345458b8d7c7538a3644 Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Mon, 23 Jul 2018 23:06:35 +0200 Subject: [PATCH] Apply pattern to make `find_or_create` atomic --- app/models/site_statistic.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/models/site_statistic.rb b/app/models/site_statistic.rb index 63566bca60c..c07233c48ed 100644 --- a/app/models/site_statistic.rb +++ b/app/models/site_statistic.rb @@ -25,17 +25,20 @@ class SiteStatistic < ActiveRecord::Base return unless available? - # we have quite a lot of specs testing migrations, we need this and the rescue to not break them - SiteStatistic.transaction(requires_new: true) do - SiteStatistic.first_or_create - attribute = self.connection.quote_column_name(raw_attribute) + self.fetch # make sure record exists - yield(attribute) - end + attribute = self.connection.quote_column_name(raw_attribute) + + # will be running on its own transaction context + yield(attribute) end def self.fetch - SiteStatistic.first_or_create! + SiteStatistic.transaction(requires_new: true) do + SiteStatistic.first_or_create! + end + rescue ActiveRecord::RecordNotUnique + retry end def self.available?