Class: Deimos::ActiveRecordConsumer

Inherits:
Consumer show all
Defined in:
lib/deimos/active_record_consumer.rb

Overview

Consumer that automatically saves the payload into the database.

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Consumer

#around_consume

Methods inherited from BaseConsumer

#decode_key, decoder, key_decoder

Class Method Details

.record_class(klass) ⇒ Object

param klass [Class < ActiveRecord::Base] the class used to save to the database.



11
12
13
# File 'lib/deimos/active_record_consumer.rb', line 11

def record_class(klass)
  config[:record_class] = klass
end

Instance Method Details

#assign_key(record, _payload, key) ⇒ Object

Assign a key to a new record.



31
32
33
# File 'lib/deimos/active_record_consumer.rb', line 31

def assign_key(record, _payload, key)
  record[record.class.primary_key] = key
end

#consume(payload, metadata) ⇒ Object

:nodoc:



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/deimos/active_record_consumer.rb', line 36

def consume(payload, )
  key = .with_indifferent_access[:key]
  klass = self.class.config[:record_class]
  record = fetch_record(klass, (payload || {}).with_indifferent_access, key)
  if payload.nil?
    destroy_record(record)
    return
  end
  if record.blank?
    record = klass.new
    assign_key(record, payload, key)
  end
  attrs = record_attributes(payload.with_indifferent_access)
  # don't use attributes= - bypass Rails < 5 attr_protected
  attrs.each do |k, v|
    record.send("#{k}=", v)
  end
  record.created_at ||= Time.zone.now if record.respond_to?(:created_at)
  record.updated_at ||= Time.zone.now if record.respond_to?(:updated_at)
  record.save!
end

#destroy_record(record) ⇒ Object

Destroy a record that received a null payload. Override if you need to do something other than a straight destroy (e.g. mark as archived).



61
62
63
# File 'lib/deimos/active_record_consumer.rb', line 61

def destroy_record(record)
  record&.destroy
end

#fetch_record(klass, _payload, key) ⇒ ActiveRecord::Base

Find the record specified by the given payload and key. Default is to use the primary key column and the value of the first field in the key.



23
24
25
# File 'lib/deimos/active_record_consumer.rb', line 23

def fetch_record(klass, _payload, key)
  klass.unscoped.where(klass.primary_key => key).first
end

#record_attributes(payload) ⇒ Object

Override this method (with super) if you want to add/change the default attributes set to the new/existing record.



68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/deimos/active_record_consumer.rb', line 68

def record_attributes(payload)
  klass = self.class.config[:record_class]
  attributes = {}
  self.class.decoder.schema_fields.each do |field|
    column = klass.columns.find { |c| c.name == field.name }
    next if column.nil?
    next if %w(updated_at created_at).include?(field.name)

    attributes[field.name] = _coerce_field(column, payload[field.name])
  end
  attributes
end