Module: Dino::Upsert

Extended by:
ActiveSupport::Concern
Defined in:
lib/dino_upsert.rb

Overview

Provides a simple way to do an create or update of an ActiveRecord object.

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Class Method Details

.upsert(klass, conditions, options = {}, &block) ⇒ Object

klass: The ActiveRecord class we are upserting against. conditions: what should match the upsert options: what we are updating/inserting If provided, the block gets the object before it’s saved, in case

there's special init options necessary for it.

rubocop:disable MethodLength



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/dino_upsert.rb', line 21

def self.upsert(klass, conditions, options = {}, &block)
  retry_count = 0
  begin
    klass.transaction(requires_new: true) do
      klass.where(conditions).first_or_initialize(&block).tap { |t| t.update!(options) }
    end
  rescue PG::UniqueViolation, ActiveRecord::RecordNotUnique
    # If there's a unique violation, retry this. But only a certain amount
    # of times or we'll get into an infinite loop if something's messed up.
    # (like an incorrect unique index or something)
    if retry_count < 10
      retry_count += 1 && retry
    else
      raise
    end
  end
end