Class: Pageturner

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

Defined Under Namespace

Classes: Exception

Constant Summary collapse

ASC =
"asc"
COMPARATOR_INTERNAL_BUG =
"sort_direction input has an unexpected value. Contact Pageturner mantainer for support."
DESC =
"desc"
GREATER_THAN_OPERATOR =
">"
LESS_THAN_OPERATOR =
"<"

Instance Method Summary collapse

Constructor Details

#initialize(anchor_column:, anchor_value:, ar_relation:, sort_direction:, page_size:, path_helper:, anchor_id:) ⇒ Pageturner

Returns a new instance of Pageturner.

Parameters:

  • anchor_column (String)
    • Field to paginate on.

  • anchor_value (String|Number|nil)
    • Value of the anchor_column for the record to paginate from.

  • ar_relation (ActiveRecord::Relation)
    • Resource collection to paginate.

  • sort_direction (String)
    • Order of the pagination. Valid values: Pageturner::ASC, Pageturner::DESC.

  • path_helper (Proc)
    • Function that generates the next page link. This function should have any state that’s not relevant to pagination partially applied.

  • anchor_id (Number)
    • ID of the record to paginate from.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/pageturner.rb', line 14

def initialize(anchor_column:, anchor_value:, ar_relation:, sort_direction:, page_size:, path_helper:, anchor_id:)
  # To be used outside dynamic SQL statements.
  @anchor_column = anchor_column

  # To be used in dynamic SQL queries.
  @sql_anchor_column = ActiveRecord::Base.connection.quote_column_name(anchor_column)

  @anchor_value = anchor_value

  @ar_relation = ar_relation

  # Always select id to use it as secondary sort to prevent non-deterministic ordering when primary sort is on a non-unique column.
  unless primary_key_selected?(@ar_relation)
    raise Exception::PrimaryKeyNotSelected, "The provided ActiveRecord::Relation does not have the primary key selected. Cursor pagination requires a primary key to paginate undeterministic columns."
  end

  @sort_direction = sort_direction
  @page_size = page_size
  @path_helper = path_helper
  @anchor_id = anchor_id

  unless [Pageturner::ASC, Pageturner::DESC].include?(@sort_direction)
    raise Exception::InvalidSortDirection, "The provided order is not supported. Supported order values are: '#{ASC}', '#{DESC}'"
  end
end

Instance Method Details

#next_pageObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/pageturner.rb', line 47

def next_page
  anchor_value =
    if external_anchor_column?
      public_send_chain_from_sql(self.resources.last, @anchor_column)
    else
      self.resources.last&.public_send(@anchor_column)
    end

  @path_helper.call(
    anchor_column: @anchor_column,
    anchor_value: anchor_value,
    sort_direction: @sort_direction,
    anchor_id: self.resources.last&.id
  )
end

#resourcesObject



40
41
42
43
44
45
# File 'lib/pageturner.rb', line 40

def resources
  # Memoize expensive querying.
  return @result if defined?(@result)

  @result = calculate_resources
end