Class: PaperTrailDiff::AnalysisBatch
- Inherits:
-
Object
- Object
- PaperTrailDiff::AnalysisBatch
- Defined in:
- lib/paper_trail_diff/analysis_batch.rb,
sig/generated/paper_trail_diff/analysis_batch.rbs
Overview
Builds one Analysis per root over a shared range, selecting every root's versions and preparing their association history once for the whole batch rather than once per root.
Instance Method Summary collapse
-
#analysis_for(record, plan) ⇒ Analysis
A root with no versions in range has nothing to report, which is an empty result rather than a failed request.
-
#call ⇒ Hash[identity, Analysis]
: () -> Hash[identity, Analysis].
-
#initialize(records, time_range:, live_loader:, history_preparer:, analyzer:, version_scope: nil, close_on_current: false) ⇒ AnalysisBatch
constructor
: (Array, time_range: TimeRange?, live_loader: untyped, history_preparer: untyped, analyzer: untyped, ?version_scope: untyped, ?close_on_current: bool) -> void.
-
#prepare(records, selected, loaded) ⇒ void
Association history is prepared per model class across every selected root version, which is the work that would otherwise repeat for each record.
-
#validated_records ⇒ Array[untyped]
: () -> Array.
-
#validated_scope(scope) ⇒ Object
A filter is a callable that narrows the version relation, so it is checked up front rather than failing partway through a batch.
Constructor Details
#initialize(records, time_range:, live_loader:, history_preparer:, analyzer:, version_scope: nil, close_on_current: false) ⇒ AnalysisBatch
: (Array, time_range: TimeRange?, live_loader: untyped, history_preparer: untyped, analyzer: untyped, ?version_scope: untyped, ?close_on_current: bool) -> void
10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/paper_trail_diff/analysis_batch.rb', line 10 def initialize( # rubocop:disable Metrics/ParameterLists records, time_range:, live_loader:, history_preparer:, analyzer:, version_scope: nil, close_on_current: false ) @records = records @time_range = time_range @version_scope = validated_scope(version_scope) @close_on_current = close_on_current @live_loader = live_loader @history_preparer = history_preparer @analyzer = analyzer end |
Instance Method Details
#analysis_for(record, plan) ⇒ Analysis
A root with no versions in range has nothing to report, which is an empty result rather than a failed request. : (untyped, RootVersionPlan) -> Analysis
90 91 92 93 94 |
# File 'lib/paper_trail_diff/analysis_batch.rb', line 90 def analysis_for(record, plan) return Analysis.empty if plan.empty? @analyzer.call(record, plan) end |
#call ⇒ Hash[identity, Analysis]
: () -> Hash[identity, Analysis]
24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/paper_trail_diff/analysis_batch.rb', line 24 def call records = validated_records loaded = @live_loader.call(records) selected = BatchedRootVersions.new( records, time_range: @time_range, version_scope: @version_scope, live_endpoints: (loaded if @close_on_current) ).call prepare(records, selected, loaded) records.to_h do |record| key = Endpoint.identity(record) plan = selected.fetch(key, RootVersionPlan.empty) [Support.immutable_copy(key), analysis_for(record, plan)] end.freeze end |
#prepare(records, selected, loaded) ⇒ void
This method returns an undefined value.
Association history is prepared per model class across every selected root version, which is the work that would otherwise repeat for each record. The roots are preloaded first, because preparation reads their current association state as a fallback and would otherwise walk it one root at a time. : (Array, Hash[Array[String], RootVersionPlan], Hash[Array[String], untyped]) -> void
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/paper_trail_diff/analysis_batch.rb', line 75 def prepare(records, selected, loaded) records.group_by(&:class).each_value do |grouped| versions = grouped.flat_map do |record| selected.fetch(Endpoint.identity(record), RootVersionPlan.empty).versions end next if versions.empty? roots = grouped.map { |record| loaded.fetch(Endpoint.identity(record), record) } @history_preparer.call(roots, versions) end end |
#validated_records ⇒ Array[untyped]
: () -> Array
59 60 61 62 63 64 65 66 67 |
# File 'lib/paper_trail_diff/analysis_batch.rb', line 59 def validated_records raise ConfigurationError, 'records: must be an array' unless @records.is_a?(Array) @records.each { |record| Endpoint.validate!(record) } identities = @records.map { |record| Endpoint.identity(record) } return @records if identities.uniq.length == identities.length raise ConfigurationError, 'records: identities must be unique' end |
#validated_scope(scope) ⇒ Object
A filter is a callable that narrows the version relation, so it is checked up front rather than failing partway through a batch. : (untyped) -> untyped
52 53 54 55 56 |
# File 'lib/paper_trail_diff/analysis_batch.rb', line 52 def validated_scope(scope) return scope if scope.nil? || scope.respond_to?(:call) raise ConfigurationError, 'version_scope: must respond to call' end |