Class: PaperTrailDiff::TimeRange

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

Overview

Validates and applies a finite wall-clock range without loading model state.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ TimeRange

: (untyped) -> void

Parameters:

  • (Object)


11
12
13
14
15
16
17
18
19
20
21
# File 'lib/paper_trail_diff/time_range.rb', line 11

def initialize(value)
  unless value.is_a?(Range) && value.begin && value.end
    raise InvalidTimeRangeError, '`within` must be a finite Range'
  end

  @begin_time = coerce_time(value.begin, boundary: :begin)
  @end_time = coerce_time(value.end, boundary: :end)
  @exclude_end = value.exclude_end?
  validate_order!
  freeze
end

Instance Attribute Details

#begin_timeTime (readonly)

Signature:

  • Time

Returns:

  • (Time)


7
8
9
# File 'lib/paper_trail_diff/time_range.rb', line 7

def begin_time
  @begin_time
end

#end_timeTime (readonly)

Signature:

  • Time

Returns:

  • (Time)


8
9
10
# File 'lib/paper_trail_diff/time_range.rb', line 8

def end_time
  @end_time
end

Instance Method Details

#coerce_time(value, boundary:) ⇒ Time

: (untyped, boundary: Symbol) -> Time

Parameters:

  • (Object)
  • boundary: (Symbol)

Returns:

  • (Time)


58
59
60
61
62
63
64
65
66
67
68
# File 'lib/paper_trail_diff/time_range.rb', line 58

def coerce_time(value, boundary:)
  unless value.respond_to?(:to_time)
    raise InvalidTimeRangeError, "`within` #{boundary} must be time-like"
  end

  time_value(value).getutc.freeze
rescue ArgumentError, NoMethodError, TypeError => e
  raise InvalidTimeRangeError,
        "`within` #{boundary} must be time-like",
        cause: e
end

#exclude_end?Boolean

: () -> bool

Returns:

  • (Boolean)


24
25
26
# File 'lib/paper_trail_diff/time_range.rb', line 24

def exclude_end?
  @exclude_end
end

#include?(value) ⇒ Boolean

: (untyped) -> bool

Parameters:

  • (Object)

Returns:

  • (Boolean)


29
30
31
32
33
34
# File 'lib/paper_trail_diff/time_range.rb', line 29

def include?(value)
  timestamp = coerce_time(value, boundary: :timestamp)
  return false if timestamp < begin_time

  exclude_end? ? timestamp < end_time : timestamp <= end_time
end

#query_rangeRange[Time]

: () -> Range

Returns:

  • (Range[Time])


53
54
55
# File 'lib/paper_trail_diff/time_range.rb', line 53

def query_range
  exclude_end? ? (begin_time...end_time) : (begin_time..end_time)
end

#scope(relation) ⇒ Object

: (untyped) -> untyped

Parameters:

  • (Object)

Returns:

  • (Object)


37
38
39
# File 'lib/paper_trail_diff/time_range.rb', line 37

def scope(relation)
  relation.where(created_at: query_range)
end

#time_value(value) ⇒ Time

: (untyped) -> Time

Parameters:

  • (Object)

Returns:

  • (Time)


71
72
73
74
75
76
# File 'lib/paper_trail_diff/time_range.rb', line 71

def time_value(value)
  return value if value.is_a?(Time)

  utc = value.utc if value.respond_to?(:utc)
  utc.is_a?(Time) ? utc : value.to_time
end

#trailing_scope(relation) ⇒ Object

: (untyped) -> untyped

Parameters:

  • (Object)

Returns:

  • (Object)


42
43
44
45
46
# File 'lib/paper_trail_diff/time_range.rb', line 42

def trailing_scope(relation)
  column = relation.klass.arel_table[:created_at]
  predicate = exclude_end? ? column.gteq(end_time) : column.gt(end_time)
  relation.where(predicate)
end

#validate_order!void

This method returns an undefined value.

: () -> void



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

def validate_order!
  return unless begin_time > end_time

  raise InvalidTimeRangeError, '`within` beginning must not follow its end'
end