Class: PaperTrailDiff::ActivityTransactionGrouper
- Inherits:
-
Object
- Object
- PaperTrailDiff::ActivityTransactionGrouper
- Defined in:
- lib/paper_trail_diff/activity_transaction_grouper.rb,
sig/generated/paper_trail_diff/activity_transaction_grouper.rbs
Overview
Reports one saved transaction as one activity step.
A parent and its children saved together produce a version each, and the timeline reports the gap between every pair of them. One deliberate action therefore arrives as several steps, none of which is the thing the person did.
A version records the state before its own event. Two things follow.
The change a step reports was made by the event that opens it, so a step
belongs to the transaction of its from_boundary, and consecutive steps
sharing one are the parts of a single save. Grouping on the closing boundary
instead would credit each change to whoever made the next one.
And a child's new value is revealed only by something later -- a further version of that child, its destroy version, or the live row. Inside a transaction there is usually none of those yet, so a step can read as empty while a change was in fact made at that boundary, and the change surfaces later, folded in with whatever that step carried. Grouping puts it back together with the save it belongs to.
Merging compares the group's outer snapshots rather than combining the diffs between them. A field set and then restored inside one transaction has not changed, and only a comparison of the endpoints can say so.
A boundary with no transaction groups with nothing. PaperTrail leaves the column nil outside a transaction, and a custom version class need not carry it at all; treating those as one shared transaction would merge unrelated history into a single step.
Instance Method Summary collapse
-
#call ⇒ Array[ActivityStep]
: () -> Array.
-
#continues?(open_group, step) ⇒ Boolean
: (Array, ActivityStep) -> bool.
-
#initialize(steps, retain:) ⇒ ActivityTransactionGrouper
constructor
: (Array, retain: bool) -> void.
-
#merge(group) ⇒ ActivityStep
Rebuilt rather than reused even when a group holds one step, so that every returned step retains its snapshots on the same terms.
Constructor Details
#initialize(steps, retain:) ⇒ ActivityTransactionGrouper
: (Array, retain: bool) -> void
36 37 38 39 |
# File 'lib/paper_trail_diff/activity_transaction_grouper.rb', line 36 def initialize(steps, retain:) @steps = steps @retain = retain end |
Instance Method Details
#call ⇒ Array[ActivityStep]
: () -> Array
42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/paper_trail_diff/activity_transaction_grouper.rb', line 42 def call grouped = [] #: Array[Array[ActivityStep]] @steps.each do |step| open_group = grouped.last if open_group && continues?(open_group, step) open_group << step else grouped << [step] end end grouped.map { |group| merge(group) } end |
#continues?(open_group, step) ⇒ Boolean
: (Array, ActivityStep) -> bool
61 62 63 64 65 66 |
# File 'lib/paper_trail_diff/activity_transaction_grouper.rb', line 61 def continues?(open_group, step) transaction = step.from_boundary.transaction_id return false if transaction.nil? open_group.last.from_boundary.transaction_id == transaction end |
#merge(group) ⇒ ActivityStep
Rebuilt rather than reused even when a group holds one step, so that every returned step retains its snapshots on the same terms. : (Array) -> ActivityStep
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/paper_trail_diff/activity_transaction_grouper.rb', line 71 def merge(group) first = group.first #: ActivityStep last = group.last #: ActivityStep ActivityStep.between( from_boundary: first.from_boundary, to_boundary: last.to_boundary, from_snapshot: first.from_snapshot, to_snapshot: last.to_snapshot, retain: @retain ) end |