Class: PaperTrailDiff::ActivityBelongsToEventApplier

Inherits:
Object
  • Object
show all
Defined in:
lib/paper_trail_diff/activity_belongs_to_event_applier.rb,
sig/generated/paper_trail_diff/activity_belongs_to_event_applier.rbs

Overview

Applies selected non-polymorphic belongs-to target updates to a snapshot.

Instance Method Summary collapse

Constructor Details

#initialize(route_finder:, record_resolver:, record_normalizer:) ⇒ ActivityBelongsToEventApplier

: (route_finder: ActivityEventRouteFinder, record_resolver: ActivityEventRecordResolver, record_normalizer: ActivityEventRecordNormalizer) -> void

Parameters:



8
9
10
11
12
# File 'lib/paper_trail_diff/activity_belongs_to_event_applier.rb', line 8

def initialize(route_finder:, record_resolver:, record_normalizer:)
  @route_finder = route_finder
  @record_resolver = record_resolver
  @record_normalizer = record_normalizer
end

Instance Method Details

#call(root_endpoint, context_endpoint, previous, tree, normalizer, version) ⇒ [ bool, RecordSnapshot? ]

: (untyped, untyped, RecordSnapshot, AssociationTree, SnapshotNormalizer, untyped) -> [bool, RecordSnapshot?]

Parameters:

Returns:



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/paper_trail_diff/activity_belongs_to_event_applier.rb', line 15

def call( # rubocop:disable Metrics/ParameterLists
  root_endpoint,
  context_endpoint,
  previous,
  tree,
  normalizer,
  version
)
  return [false, nil] unless %w[update destroy].include?(version.event.to_s)

  routes = @route_finder.belongs_to_routes(
    endpoint_model_class(root_endpoint), tree, version.item_type.to_s
  )
  return [false, nil] if routes.empty?

  snapshot = previous
  routes.each do |route|
    replacement = normalized_route_record(
      route, version, normalizer, root_endpoint, context_endpoint
    )
    snapshot, = replace_route(snapshot, route, version, replacement)
  end
  [true, snapshot]
end

#endpoint_model_class(endpoint) ⇒ Object

: (untyped) -> untyped

Parameters:

  • (Object)

Returns:

  • (Object)


122
123
124
# File 'lib/paper_trail_diff/activity_belongs_to_event_applier.rb', line 122

def endpoint_model_class(endpoint)
  Endpoint.version?(endpoint) ? Endpoint.model_class(endpoint) : endpoint.class
end

#normalized_route_record(route, version, normalizer, root_endpoint, context_endpoint) ⇒ RecordSnapshot?

: (Array, untyped, SnapshotNormalizer, untyped, untyped) -> RecordSnapshot?

Parameters:

Returns:



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/paper_trail_diff/activity_belongs_to_event_applier.rb', line 47

def normalized_route_record(route, version, normalizer, root_endpoint, context_endpoint)
  record = @record_resolver.record_after(version)
  return unless record

  _name, reflection, subtree, path = route.last
  @record_normalizer.call(
    record,
    reflection: reflection,
    subtree: subtree,
    path: path,
    normalizer: normalizer,
    root_endpoint: root_endpoint,
    context_endpoint: context_endpoint
  )
end

#replace_association(snapshot, name, association) ⇒ RecordSnapshot

: (RecordSnapshot, String, AssociationSnapshot) -> RecordSnapshot

Parameters:

Returns:



105
106
107
108
109
110
111
112
# File 'lib/paper_trail_diff/activity_belongs_to_event_applier.rb', line 105

def replace_association(snapshot, name, association)
  RecordSnapshot.new(
    type: snapshot.type,
    id: snapshot.id,
    attributes: snapshot.attributes,
    associations: snapshot.associations.merge(name => association)
  )
end

#replace_existing_target(records, version, replacement) ⇒ [ Array[RecordSnapshot], bool ]

: (Array, untyped, RecordSnapshot?) -> [Array[RecordSnapshot], bool]

Parameters:

Returns:



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/paper_trail_diff/activity_belongs_to_event_applier.rb', line 92

def replace_existing_target(records, version, replacement)
  index = records.index do |record|
    record.id.to_s == version.item_id.to_s &&
      record.type.to_s == replacement_type(version, replacement)
  end
  return [records, false] unless index

  updated = records.dup
  replacement ? updated[index] = replacement : updated.delete_at(index)
  [updated.freeze, true]
end

#replace_route(snapshot, route, version, replacement, depth: 0) ⇒ [ RecordSnapshot, bool ]

: (RecordSnapshot, Array, untyped, RecordSnapshot?, ?depth: Integer) -> [RecordSnapshot, bool]

Parameters:

Returns:



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/paper_trail_diff/activity_belongs_to_event_applier.rb', line 64

def replace_route(snapshot, route, version, replacement, depth: 0)
  name, _reflection, _subtree, = route.fetch(depth)
  association = snapshot.associations.fetch(name)
  records, changed = replacement_records(
    association.records, route, version, replacement, depth
  )
  return [snapshot, false] unless changed

  updated_association = AssociationSnapshot.new(kind: association.kind, records: records)
  [replace_association(snapshot, name, updated_association), true]
end

#replacement_records(records, route, version, replacement, depth) ⇒ [ Array[RecordSnapshot], bool ]

: (Array, Array, untyped, RecordSnapshot?, Integer) -> [Array[RecordSnapshot], bool]

Parameters:

Returns:



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/paper_trail_diff/activity_belongs_to_event_applier.rb', line 77

def replacement_records(records, route, version, replacement, depth)
  return replace_existing_target(records, version, replacement) if depth == route.length - 1

  changed = false
  updated = records.map do |record|
    result, record_changed = replace_route(
      record, route, version, replacement, depth: depth + 1
    )
    changed ||= record_changed
    result
  end.freeze
  [updated, changed]
end

#replacement_type(version, replacement) ⇒ String

: (untyped, RecordSnapshot?) -> String

Parameters:

Returns:

  • (String)


115
116
117
118
119
# File 'lib/paper_trail_diff/activity_belongs_to_event_applier.rb', line 115

def replacement_type(version, replacement)
  return replacement.type.to_s if replacement

  Endpoint.model_class(version).name.to_s
end