Class: ActiveRecordCursorPaginate::Cursor

Inherits:
Object
  • Object
show all
Defined in:
lib/activerecord_cursor_paginate/cursor.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(columns:, values:) ⇒ Cursor

Returns a new instance of Cursor.

Raises:

  • (ArgumentError)


49
50
51
52
53
54
55
# File 'lib/activerecord_cursor_paginate/cursor.rb', line 49

def initialize(columns:, values:)
  @columns = Array.wrap(columns)
  @values = Array.wrap(values)

  raise ArgumentError, "Cursor values can not be nil" if @values.any?(nil)
  raise ArgumentError, ":columns and :values have different sizes" if @columns.size != @values.size
end

Instance Attribute Details

#columnsObject (readonly)

Returns the value of attribute columns.



47
48
49
# File 'lib/activerecord_cursor_paginate/cursor.rb', line 47

def columns
  @columns
end

#valuesObject (readonly)

Returns the value of attribute values.



47
48
49
# File 'lib/activerecord_cursor_paginate/cursor.rb', line 47

def values
  @values
end

Class Method Details

.decode(cursor_string:, columns:) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/activerecord_cursor_paginate/cursor.rb', line 15

def decode(cursor_string:, columns:)
  decoded = JSON.parse(Base64.urlsafe_decode64(cursor_string))

  if (columns.size == 1 && decoded.is_a?(Array)) ||
     (decoded.is_a?(Array) && decoded.size != columns.size)
    raise InvalidCursorError,
          "The given cursor `#{cursor_string}` was decoded as `#{decoded}` but could not be parsed"
  end

  decoded =
    if decoded.is_a?(Array)
      decoded.map { |value| deserialize_time_if_needed(value) }
    else
      deserialize_time_if_needed(decoded)
    end

  new(columns: columns, values: decoded)
rescue ArgumentError, JSON::ParserError # ArgumentError is raised by strict_decode64
  raise InvalidCursorError, "The given cursor `#{cursor_string}` could not be decoded"
end

.from_record(record, columns:) ⇒ Object



10
11
12
13
# File 'lib/activerecord_cursor_paginate/cursor.rb', line 10

def from_record(record, columns:)
  values = columns.map { |column| record[column] }
  new(columns: columns, values: values)
end

Instance Method Details

#encodeObject



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/activerecord_cursor_paginate/cursor.rb', line 57

def encode
  serialized_values = values.map do |value|
    if value.is_a?(Time)
      TIMESTAMP_PREFIX + value.strftime("%s%6N")
    else
      value
    end
  end
  unencoded_cursor = (serialized_values.size == 1 ? serialized_values.first : serialized_values)
  Base64.urlsafe_encode64(unencoded_cursor.to_json, padding: false)
end