Class: PaperTrailDiff::PreparedHistoryLoader
- Inherits:
-
Object
- Object
- PaperTrailDiff::PreparedHistoryLoader
- Defined in:
- lib/paper_trail_diff/prepared_history_loader.rb,
sig/generated/paper_trail_diff/prepared_history_loader.rbs
Overview
Expands the explicit association tree into a request-scoped PreparedHistory.
Instance Method Summary collapse
-
#call ⇒ PreparedHistory
: () -> PreparedHistory.
-
#deferred_macro?(reflection) ⇒ Boolean
: (untyped) -> bool.
-
#edge_key(owner_class, reflection) ⇒ Array[String]
: (untyped, untyped) -> Array.
- #initialize(record, root_versions:, tree:, traversal:, root_ids: [record.id], start_at: root_versions.first.created_at, end_at: nil, live_records: []) ⇒ PreparedHistoryLoader constructor
-
#load_groups(groups) ⇒ void
: (Hash[String, Hash[Symbol, untyped]]) -> void.
-
#load_node(model_class, ids, tree, path:) ⇒ void
: (untyped, Array, AssociationTree, path: String) -> void.
-
#load_records(model_class, ids) ⇒ void
: (untyped, Array) -> void.
-
#mark_prepared(owner_class, ids, reflection) ⇒ void
: (untyped, Array, untyped) -> void.
-
#mark_unsupported(owner_class, reflection, groups) ⇒ void
: (untyped, untyped, Hash[String, Hash[Symbol, untyped]]) -> void.
-
#merge_groups(left, right) ⇒ Hash[String, Hash[Symbol, untyped]]
: (Hash[String, Hash[Symbol, untyped]], Hash[String, Hash[Symbol, untyped]]) -> Hash[String, Hash[Symbol, untyped]].
-
#prepare_edge(owner_class, owner_ids, reflection) ⇒ Hash[String, Hash[Symbol, untyped]]
: (untyped, Array, untyped) -> Hash[String, Hash[Symbol, untyped]].
-
#prepare_reflection(owner_class, owner_ids, reflection) ⇒ Hash[String, Hash[Symbol, untyped]]
: (untyped, Array, untyped) -> Hash[String, Hash[Symbol, untyped]].
-
#prepare_through(owner_class, owner_ids, reflection) ⇒ Hash[String, Hash[Symbol, untyped]]
: (untyped, Array, untyped) -> Hash[String, Hash[Symbol, untyped]].
- #unprepared_ids(owner_class, ids, reflection) ⇒ Array[untyped]
-
#versioned?(model_class) ⇒ Boolean
: (untyped) -> bool.
Constructor Details
#initialize(record, root_versions:, tree:, traversal:, root_ids: [record.id], start_at: root_versions.first.created_at, end_at: nil, live_records: []) ⇒ PreparedHistoryLoader
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 8 def initialize( # rubocop:disable Metrics/ParameterLists record, root_versions:, tree:, traversal:, root_ids: [record.id], start_at: root_versions.first.created_at, end_at: nil, live_records: [] ) @record = record @root_ids = root_ids @tree = tree @traversal = traversal @records = PreparedRecordIndex.new(start_at, end_at: end_at, live_records: live_records) @history = PreparedHistory.new(@records) @edges = PreparedEdgeLoader.new(@records, root_versions, start_at: start_at) @prepared = {} #: Hash[Array[String], Array[String]] end |
Instance Method Details
#call ⇒ PreparedHistory
: () -> PreparedHistory
29 30 31 32 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 29 def call load_node(@record.class, @root_ids, @tree, path: '') @history end |
#deferred_macro?(reflection) ⇒ Boolean
: (untyped) -> bool
116 117 118 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 116 def deferred_macro?(reflection) reflection.[:through] && !reflection.source_reflection.belongs_to? end |
#edge_key(owner_class, reflection) ⇒ Array[String]
: (untyped, untyped) -> Array
136 137 138 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 136 def edge_key(owner_class, reflection) [owner_class.base_class.name.to_s, reflection.name.to_s] end |
#load_groups(groups) ⇒ void
This method returns an undefined value.
: (Hash[String, Hash[Symbol, untyped]]) -> void
121 122 123 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 121 def load_groups(groups) groups.each_value { |group| load_records(group.fetch(:model), group.fetch(:ids)) } end |
#load_node(model_class, ids, tree, path:) ⇒ void
This method returns an undefined value.
: (untyped, Array, AssociationTree, path: String) -> void
46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 46 def load_node(model_class, ids, tree, path:) @traversal.reflections_for(model_class, tree, path: path).each do |reflection| subtree = tree.child(reflection.name) next unless subtree groups = prepare_reflection(model_class, ids, reflection) load_groups(groups) child_path = Support.association_path(path, reflection.name.to_s) groups.each_value do |group| load_node(group.fetch(:model), group.fetch(:ids), subtree, path: child_path) end end end |
#load_records(model_class, ids) ⇒ void
This method returns an undefined value.
: (untyped, Array) -> void
126 127 128 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 126 def load_records(model_class, ids) @records.load(model_class, ids) if versioned?(model_class) end |
#mark_prepared(owner_class, ids, reflection) ⇒ void
This method returns an undefined value.
: (untyped, Array, untyped) -> void
103 104 105 106 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 103 def mark_prepared(owner_class, ids, reflection) key = edge_key(owner_class, reflection) @prepared[key] = (@prepared.fetch(key, []) | ids.map(&:to_s)) end |
#mark_unsupported(owner_class, reflection, groups) ⇒ void
This method returns an undefined value.
: (untyped, untyped, Hash[String, Hash[Symbol, untyped]]) -> void
109 110 111 112 113 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 109 def mark_unsupported(owner_class, reflection, groups) unsupported = deferred_macro?(reflection) || reflection.foreign_key.is_a?(Array) || groups.values.any? { |group| !versioned?(group.fetch(:model)) } @history.mark_unsupported(owner_class, reflection) if unsupported end |
#merge_groups(left, right) ⇒ Hash[String, Hash[Symbol, untyped]]
: (Hash[String, Hash[Symbol, untyped]], Hash[String, Hash[Symbol, untyped]]) -> Hash[String, Hash[Symbol, untyped]]
141 142 143 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 141 def merge_groups(left, right) Support.merge_record_groups(left, right) end |
#prepare_edge(owner_class, owner_ids, reflection) ⇒ Hash[String, Hash[Symbol, untyped]]
: (untyped, Array, untyped) -> Hash[String, Hash[Symbol, untyped]]
82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 82 def prepare_edge(owner_class, owner_ids, reflection) missing = unprepared_ids(owner_class, owner_ids, reflection) return @history.edge(owner_class, reflection) if missing.empty? load_records(owner_class, missing) if reflection.macro == :belongs_to groups, memberships = @edges.call(owner_class, missing, reflection) @history.merge_edge(owner_class, reflection, groups) @history.register_habtm(owner_class, reflection, memberships) if memberships mark_prepared(owner_class, missing, reflection) mark_unsupported(owner_class, reflection, groups) load_groups(groups) @history.edge(owner_class, reflection) end |
#prepare_reflection(owner_class, owner_ids, reflection) ⇒ Hash[String, Hash[Symbol, untyped]]
: (untyped, Array, untyped) -> Hash[String, Hash[Symbol, untyped]]
61 62 63 64 65 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 61 def prepare_reflection(owner_class, owner_ids, reflection) return prepare_through(owner_class, owner_ids, reflection) if reflection.[:through] prepare_edge(owner_class, owner_ids, reflection) end |
#prepare_through(owner_class, owner_ids, reflection) ⇒ Hash[String, Hash[Symbol, untyped]]
: (untyped, Array, untyped) -> Hash[String, Hash[Symbol, untyped]]
68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 68 def prepare_through(owner_class, owner_ids, reflection) through_groups = prepare_edge(owner_class, owner_ids, reflection.through_reflection) targets = {} #: Hash[String, Hash[Symbol, untyped]] through_groups.each_value do |group| load_groups({ group.fetch(:model).name.to_s => group }) source = prepare_edge(group.fetch(:model), group.fetch(:ids), reflection.source_reflection) targets = merge_groups(targets, source) end @history.merge_edge(owner_class, reflection, targets) @history.mark_unsupported(owner_class, reflection) if deferred_macro?(reflection) targets end |
#unprepared_ids(owner_class, ids, reflection) ⇒ Array[untyped]
97 98 99 100 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 97 def unprepared_ids(owner_class, ids, reflection) prepared = @prepared.fetch(edge_key(owner_class, reflection), []) ids.reject { |id| prepared.include?(id.to_s) } end |
#versioned?(model_class) ⇒ Boolean
: (untyped) -> bool
131 132 133 |
# File 'lib/paper_trail_diff/prepared_history_loader.rb', line 131 def versioned?(model_class) model_class.respond_to?(:paper_trail) end |