Class: Deimos::ActiveRecordConsume::BatchRecord

Inherits:
Object
  • Object
show all
Defined in:
lib/deimos/active_record_consume/batch_record.rb

Overview

Keeps track of both an ActiveRecord instance and more detailed attributes. The attributes are needed for nested associations.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass:, attributes:, bulk_import_column: nil) ⇒ BatchRecord

Returns a new instance of BatchRecord.

Parameters:

  • klass (Class < ActiveRecord::Base])

    lass [Class < ActiveRecord::Base]

  • attributes (Hash)

    the full attribute list, including associations.

  • bulk_import_column (String) (defaults to: nil)


25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/deimos/active_record_consume/batch_record.rb', line 25

def initialize(klass:, attributes:, bulk_import_column: nil)
  @klass = klass
  if bulk_import_column
    self.bulk_import_column = bulk_import_column
    self.bulk_import_id = SecureRandom.uuid
    attributes[bulk_import_column] = bulk_import_id
  end
  attributes = attributes.with_indifferent_access
  self.record = klass.new(attributes.slice(*klass.column_names))
  assoc_keys = attributes.keys.select { |k| klass.reflect_on_association(k) }
  # a hash with just the association keys, removing all actual column information.
  self.associations = attributes.slice(*assoc_keys)
  validate_import_id! if self.associations.any?
end

Instance Attribute Details

#associationsHash

For has_one, the format would be e.g. { ‘detail’ => { ‘foo’ => ‘bar’}}. For has_many, it would be an array, e.g. { ‘details’ => [=> ‘bar’, => ‘baz’]}

Returns:

  • (Hash)

    a set of association information, represented by a hash of attributes.



13
14
15
# File 'lib/deimos/active_record_consume/batch_record.rb', line 13

def associations
  @associations
end

#bulk_import_columnString

Returns The column name to use for bulk IDs - defaults to ‘bulk_import_id`.

Returns:

  • (String)

    The column name to use for bulk IDs - defaults to ‘bulk_import_id`.



18
19
20
# File 'lib/deimos/active_record_consume/batch_record.rb', line 18

def bulk_import_column
  @bulk_import_column
end

#bulk_import_idString

the in-memory record.

Returns:

  • (String)

    A unique UUID used to associate the auto-increment ID back to



16
17
18
# File 'lib/deimos/active_record_consume/batch_record.rb', line 16

def bulk_import_id
  @bulk_import_id
end

#recordActiveRecord::Base

Returns:

  • (ActiveRecord::Base)


9
10
11
# File 'lib/deimos/active_record_consume/batch_record.rb', line 9

def record
  @record
end

Instance Method Details

#klassClass < ActiveRecord::Base]

Returns Class < ActiveRecord::Base].

Returns:

  • (Class < ActiveRecord::Base])

    Class < ActiveRecord::Base]



50
51
52
# File 'lib/deimos/active_record_consume/batch_record.rb', line 50

def klass
  self.record.class
end

#sub_records(assoc_name, bulk_import_id = nil) ⇒ Array<BatchRecord>

Create a list of BatchRecord instances representing associated objects for the given association name. parent bulk_insert_id, where each record has a unique UUID, this is used to detect and delete old data, so this is basically a “session ID” for this bulk upsert.

Parameters:

  • assoc_name (String)
  • bulk_import_id (String) (defaults to: nil)

    A UUID which should be set on every sub-record. Unlike the

Returns:



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/deimos/active_record_consume/batch_record.rb', line 62

def sub_records(assoc_name, bulk_import_id=nil)
  attr_list = self.associations[assoc_name.to_s]
  assoc = self.klass.reflect_on_association(assoc_name)
  Array.wrap(attr_list).map { |attrs|
    # Set the ID of the original object, e.g. widgets -> details, this will set widget_id.
    attrs[assoc.foreign_key] = self.record[assoc.active_record_primary_key]
    if bulk_import_id
      attrs[self.bulk_import_column] = bulk_import_id
    end
    BatchRecord.new(klass: assoc.klass, attributes: attrs) if attrs
  }.compact
end

#validate_import_id!Object

Checks whether the entities has necessary columns for association saving to work

Returns:

  • void



42
43
44
45
46
47
# File 'lib/deimos/active_record_consume/batch_record.rb', line 42

def validate_import_id!
  return if @klass.column_names.include?(self.bulk_import_column.to_s)

  raise "Create bulk_import_id on the #{@klass.table_name} table." \
        ' Run rails g deimos:bulk_import_id {table} to create the migration.'
end