Class: ActiveRecordCursorPaginate::Paginator
- Inherits:
-
Object
- Object
- ActiveRecordCursorPaginate::Paginator
- Defined in:
- lib/activerecord_cursor_paginate/paginator.rb
Overview
Use this Paginator class to effortlessly paginate through ActiveRecord relations using cursor pagination.
Instance Method Summary collapse
-
#fetch ⇒ ActiveRecordCursorPaginate::Page
(also: #page)
Get the paginated result.
-
#initialize(relation, before: nil, after: nil, limit: nil, order: nil, append_primary_key: true) ⇒ Paginator
constructor
Create a new instance of the ‘ActiveRecordCursorPaginate::Paginator`.
-
#pages ⇒ Enumerator
Returns an enumerator that can be used to iterate over the whole relation.
Constructor Details
#initialize(relation, before: nil, after: nil, limit: nil, order: nil, append_primary_key: true) ⇒ Paginator
Create a new instance of the ‘ActiveRecordCursorPaginate::Paginator`
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/activerecord_cursor_paginate/paginator.rb', line 43 def initialize(relation, before: nil, after: nil, limit: nil, order: nil, append_primary_key: true) unless relation.is_a?(ActiveRecord::Relation) raise ArgumentError, "relation is not an ActiveRecord::Relation" end if before.present? && after.present? raise ArgumentError, "Only one of :before and :after can be provided" end @relation = relation @primary_key = @relation.primary_key @cursor = before || after @is_forward_pagination = before.blank? config = ActiveRecordCursorPaginate.config @page_size = limit || config.default_page_size @page_size = [@page_size, config.max_page_size].min if config.max_page_size @append_primary_key = append_primary_key order = normalize_order(order) @columns = order.keys @directions = order.values end |
Instance Method Details
#fetch ⇒ ActiveRecordCursorPaginate::Page Also known as: page
Note:
Calling this method advances the paginator.
Get the paginated result.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/activerecord_cursor_paginate/paginator.rb', line 72 def fetch relation = @relation # Non trivial columns (expressions or joined tables columns). if @columns.any?(/\W/) arel_columns = @columns.map.with_index do |column, i| arel_column(column).as("cursor_column_#{i + 1}") end cursor_column_names = arel_columns.map { |column| column.right.to_s } relation = if relation.select_values.empty? relation.select(relation.arel_table[Arel.star], arel_columns) else relation.select(arel_columns) end else cursor_column_names = @columns end pagination_directions = @directions.map { |direction| pagination_direction(direction) } relation = relation.reorder(cursor_column_names.zip(pagination_directions).to_h) if @cursor decoded_cursor = Cursor.decode(cursor_string: @cursor, columns: @columns) relation = apply_cursor(relation, decoded_cursor) end relation = relation.limit(@page_size + 1) records_plus_one = relation.to_a has_additional = records_plus_one.size > @page_size records = records_plus_one.take(@page_size) records.reverse! unless @is_forward_pagination if @is_forward_pagination has_next_page = has_additional has_previous_page = @cursor.present? else has_next_page = @cursor.present? has_previous_page = has_additional end page = Page.new( records, order_columns: cursor_column_names, has_next: has_next_page, has_previous: has_previous_page ) advance_by_page(page) unless page.empty? page end |
#pages ⇒ Enumerator
Returns an enumerator that can be used to iterate over the whole relation.
131 132 133 134 135 136 137 138 139 140 |
# File 'lib/activerecord_cursor_paginate/paginator.rb', line 131 def pages Enumerator.new do |yielder| loop do page = fetch break if page.empty? yielder.yield(page) end end end |