Class: PaperTrailDiff::ActivityEventRouteFinder

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

Overview

Finds explicitly selected collection and belongs-to routes for one event type.

Instance Method Summary collapse

Constructor Details

#initialize(traversal) ⇒ ActivityEventRouteFinder

: (AssociationTraversal) -> void

Parameters:



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

def initialize(traversal)
  @traversal = traversal
  @collection_routes = {} #: Hash[Array[untyped], Array[Array[untyped]]]
  @belongs_to_routes = {} #: Hash[Array[untyped], Array[Array[untyped]]]
end

Instance Method Details

#belongs_to_routes(model_class, tree, target_type, path: '') ⇒ Array[Array[untyped]]

: (untyped, AssociationTree, String, ?path: String) -> Array[Array[untyped]]

Parameters:

Returns:

  • (Array[Array[untyped]])


20
21
22
# File 'lib/paper_trail_diff/activity_event_route_finder.rb', line 20

def belongs_to_routes(model_class, tree, target_type, path: '')
  cached(@belongs_to_routes, model_class, tree, target_type, path, :belongs_to)
end

#cache_key(key) ⇒ Array[untyped]

: (Array) -> Array

Parameters:

  • (Array[untyped])

Returns:

  • (Array[untyped])


44
45
46
# File 'lib/paper_trail_diff/activity_event_route_finder.rb', line 44

def cache_key(key)
  key.map { |part| part.is_a?(String) ? -part : part }.freeze
end

#cached(store, model_class, tree, target_type, path, macro) ⇒ Array[Array[untyped]]

Timelines interleave event types, so every requested combination is retained. Model, tree, and path are fixed per adapter, leaving one entry per selected item type. : (Hash[Array[untyped], Array[Array[untyped]]], untyped, AssociationTree, String, String, Symbol) -> Array[Array[untyped]]

Parameters:

  • (Hash[Array[untyped], Array[Array[untyped]]])
  • (Object)
  • (AssociationTree)
  • (String)
  • (String)
  • (Symbol)

Returns:

  • (Array[Array[untyped]])


34
35
36
37
38
39
40
41
# File 'lib/paper_trail_diff/activity_event_route_finder.rb', line 34

def cached(store, model_class, tree, target_type, path, macro) # rubocop:disable Metrics/ParameterLists
  key = [model_class, tree, target_type, path]
  existing = store[key]
  return existing if existing

  store[cache_key(key)] =
    freeze_routes(routes(model_class, tree, target_type, macro, path: path))
end

#collection_routes(model_class, tree, target_type, path: '') ⇒ Array[Array[untyped]]

: (untyped, AssociationTree, String, ?path: String) -> Array[Array[untyped]]

Parameters:

Returns:

  • (Array[Array[untyped]])


15
16
17
# File 'lib/paper_trail_diff/activity_event_route_finder.rb', line 15

def collection_routes(model_class, tree, target_type, path: '')
  cached(@collection_routes, model_class, tree, target_type, path, :has_many)
end

#direct_route?(reflection, target_type, macro) ⇒ Boolean

: (untyped, String, Symbol) -> bool

Parameters:

  • (Object)
  • (String)
  • (Symbol)

Returns:

  • (Boolean)


80
81
82
83
# File 'lib/paper_trail_diff/activity_event_route_finder.rb', line 80

def direct_route?(reflection, target_type, macro)
  reflection.macro == macro && supported_direct_reflection?(reflection, macro) &&
    reflection.klass.base_class.name.to_s == target_type
end

#freeze_routes(routes) ⇒ Array[Array[untyped]]

: (Array[Array[untyped]]) -> Array[Array[untyped]]

Parameters:

  • (Array[Array[untyped]])

Returns:

  • (Array[Array[untyped]])


49
50
51
52
53
54
# File 'lib/paper_trail_diff/activity_event_route_finder.rb', line 49

def freeze_routes(routes)
  routes.each do |route|
    route.each(&:freeze)
    route.freeze
  end.freeze
end

#routes(model_class, tree, target_type, macro, path: '') ⇒ Array[Array[untyped]]

: (untyped, AssociationTree, String, Symbol, path: String) -> Array[Array[untyped]]

Parameters:

  • (Object)
  • (AssociationTree)
  • (String)
  • (Symbol)
  • path: (String) (defaults to: '')

Returns:

  • (Array[Array[untyped]])


57
58
59
60
61
# File 'lib/paper_trail_diff/activity_event_route_finder.rb', line 57

def routes(model_class, tree, target_type, macro, path: '')
  @traversal.reflections_for(model_class, tree, path: path).flat_map do |reflection|
    routes_for_reflection(reflection, tree, target_type, macro, path)
  end
end

#routes_for_reflection(reflection, tree, target_type, macro, path) ⇒ Array[Array[untyped]]

: (untyped, AssociationTree, String, Symbol, String) -> Array[Array[untyped]]

Parameters:

Returns:

  • (Array[Array[untyped]])


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

def routes_for_reflection(reflection, tree, target_type, macro, path)
  name = reflection.name.to_s
  subtree = tree.child(name)
  return [] unless subtree

  child_path = Support.association_path(path, name)
  entry = [name, reflection, subtree, child_path]
  direct = [] #: Array[Array[untyped]]
  direct << [entry] if direct_route?(reflection, target_type, macro)
  return direct if subtree.empty? || reflection.polymorphic?

  nested = routes(reflection.klass, subtree, target_type, macro, path: child_path)
  direct.concat(nested.map { |route| [entry, *route] })
end

#supported_direct_reflection?(reflection, macro) ⇒ Boolean

: (untyped, Symbol) -> bool

Parameters:

  • (Object)
  • (Symbol)

Returns:

  • (Boolean)


86
87
88
89
90
# File 'lib/paper_trail_diff/activity_event_route_finder.rb', line 86

def supported_direct_reflection?(reflection, macro)
  return !reflection.options[:through] if macro == :has_many

  !reflection.polymorphic?
end