Class: PaperTrailDiff::VersionRange

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

Overview

Selects an inclusive, chronological range from a record's root versions.

Instance Method Summary collapse

Constructor Details

#initialize(record, from:, to:, version_scope: nil) ⇒ VersionRange

: (untyped, from: untyped, to: untyped, ?version_scope: untyped) -> void

Parameters:

  • (Object)
  • from: (Object)
  • to: (Object)
  • version_scope: (Object) (defaults to: nil)


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

def initialize(record, from:, to:, version_scope: nil)
  @record = record
  @from = from
  @to = to
  @version_scope = version_scope
end

Instance Method Details

#ordered(versions) ⇒ Array[untyped]

: (Array) -> Array

Parameters:

  • (Array[untyped])

Returns:

  • (Array[untyped])


98
99
100
# File 'lib/paper_trail_diff/version_range.rb', line 98

def ordered(versions)
  Support.chronological_sort(versions)
end

#selectArray[untyped]

: () -> Array

Returns:

  • (Array[untyped])


38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/paper_trail_diff/version_range.rb', line 38

def select
  relation = versions_relation
  validate_boundary!(@from, relation, boundary: :from)
  validate_boundary!(@to, relation, boundary: :to)
  if Support.compare_versions(@from, @to).positive?
    raise InvalidTimelineRangeError, '`from` version must not follow `to` version'
  end

  select_relation(
    relation.where(created_at: @from.created_at..@to.created_at),
    through: @to
  )
end

#select_plan(relation, through: nil) ⇒ RootVersionPlan

: (untyped, ?through: untyped) -> RootVersionPlan

Parameters:

  • (Object)
  • through: (Object) (defaults to: nil)

Returns:



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/paper_trail_diff/version_range.rb', line 81

def select_plan(relation, through: nil)
  in_range = ordered(relation.to_a.select do |version|
    next false if Support.compare_versions(@from, version).positive?
    next true unless through

    Support.compare_versions(version, through) <= 0
  end)
  RootVersionSelection.new(
    in_range: in_range,
    selected: VersionScopeFilter.new(@version_scope).call(relation, in_range),
    after_range: nil,
    windowed: false,
    filtered: !@version_scope.nil?
  ).call
end

#select_plan_for_rangeRootVersionPlan

Same selection as select, but keeping the step pairs a filter implies. : () -> RootVersionPlan

Returns:



17
18
19
20
21
22
23
# File 'lib/paper_trail_diff/version_range.rb', line 17

def select_plan_for_range
  relation = validated_relation
  select_plan(
    relation.where(created_at: @from.created_at..@to.created_at),
    through: @to
  )
end

#select_relation(relation, through: nil) ⇒ Array[untyped]

: (untyped, ?through: untyped) -> Array

Parameters:

  • (Object)
  • through: (Object) (defaults to: nil)

Returns:

  • (Array[untyped])


76
77
78
# File 'lib/paper_trail_diff/version_range.rb', line 76

def select_relation(relation, through: nil)
  select_plan(relation, through: through).versions
end

#select_through_latestArray[untyped]

: () -> Array

Returns:

  • (Array[untyped])


53
54
55
56
57
# File 'lib/paper_trail_diff/version_range.rb', line 53

def select_through_latest
  relation = versions_relation
  validate_boundary!(@from, relation, boundary: :from)
  select_relation(relation.where(created_at: @from.created_at..))
end

#valid_boundary?(requested, relation) ⇒ Boolean

: (untyped, untyped) -> bool

Parameters:

  • (Object)
  • (Object)

Returns:

  • (Boolean)


113
114
115
116
117
118
119
# File 'lib/paper_trail_diff/version_range.rb', line 113

def valid_boundary?(requested, relation)
  expected_identity = [@record.class.base_class.name.to_s, @record.id.to_s]
  Endpoint.version?(requested) &&
    requested.instance_of?(relation.klass) &&
    Endpoint.identity(requested) == expected_identity &&
    relation.where(id: requested.id).exists?
end

#validate_boundary!(requested, relation, boundary:) ⇒ void

This method returns an undefined value.

: (untyped, untyped, boundary: Symbol) -> void

Parameters:

  • (Object)
  • (Object)
  • boundary: (Symbol)


103
104
105
106
107
108
109
110
# File 'lib/paper_trail_diff/version_range.rb', line 103

def validate_boundary!(requested, relation, boundary:)
  Endpoint.validate!(requested)
  return if valid_boundary?(requested, relation)

  raise InvalidTimelineRangeError, "`#{boundary}` version is not in the record history"
rescue InvalidEndpointError, NoMethodError
  raise InvalidTimelineRangeError, "`#{boundary}` version is not in the record history"
end

#validated_relationObject

: () -> untyped

Returns:

  • (Object)


26
27
28
29
30
31
32
33
34
35
# File 'lib/paper_trail_diff/version_range.rb', line 26

def validated_relation
  relation = versions_relation
  validate_boundary!(@from, relation, boundary: :from)
  validate_boundary!(@to, relation, boundary: :to)
  if Support.compare_versions(@from, @to).positive?
    raise InvalidTimelineRangeError, '`from` version must not follow `to` version'
  end

  relation
end

#versions_relationObject

: () -> untyped

Returns:

  • (Object)


67
68
69
70
71
72
73
# File 'lib/paper_trail_diff/version_range.rb', line 67

def versions_relation
  association_name = @record.class.versions_association_name
  @record.public_send(association_name)
rescue NoMethodError => e
  message = 'record does not expose a PaperTrail version history'
  raise InvalidTimelineRangeError, message, cause: e
end