@@ -20,6 +20,7 @@ module ActiveRecordCursorPaginate
2020 #
2121 class Paginator
2222 attr_reader :relation , :before , :after , :limit , :order , :append_primary_key
23+ attr_accessor :forward_pagination
2324
2425 # Create a new instance of the `ActiveRecordCursorPaginate::Paginator`
2526 #
@@ -45,10 +46,14 @@ class Paginator
4546 # It is not recommended to use this feature, because the complexity of produced SQL
4647 # queries can have a very negative impact on the database performance. It is better
4748 # to paginate using only non-nullable columns.
49+ # @param forward_pagination [Boolean] Whether this is a forward or backward pagination.
50+ # Optional, defaults to `true` if `:before` is not provided, `false` otherwise.
51+ # Useful when paginating backward from the end of the collection.
4852 #
4953 # @raise [ArgumentError] If any parameter is not valid
5054 #
51- def initialize ( relation , before : nil , after : nil , limit : nil , order : nil , append_primary_key : true , nullable_columns : nil )
55+ def initialize ( relation , before : nil , after : nil , limit : nil , order : nil , append_primary_key : true ,
56+ nullable_columns : nil , forward_pagination : before . nil? )
5257 unless relation . is_a? ( ActiveRecord ::Relation )
5358 raise ArgumentError , "relation is not an ActiveRecord::Relation"
5459 end
@@ -58,7 +63,7 @@ def initialize(relation, before: nil, after: nil, limit: nil, order: nil, append
5863 @append_primary_key = append_primary_key
5964
6065 @cursor = @current_cursor = nil
61- @is_forward_pagination = true
66+ @forward_pagination = forward_pagination
6267 @before = @after = nil
6368 @page_size = nil
6469 @limit = nil
@@ -80,17 +85,18 @@ def before=(value)
8085
8186 @cursor = value || after
8287 @current_cursor = @cursor
83- @is_forward_pagination = value . blank?
88+ @forward_pagination = false if value
8489 @before = value
8590 end
8691
8792 def after = ( value )
88- if before . present? && value . present?
93+ if value . present? && before . present?
8994 raise ArgumentError , "Only one of :before and :after can be provided"
9095 end
9196
92- @cursor = before || value
97+ @cursor = value || before
9398 @current_cursor = @cursor
99+ @forward_pagination = true if value
94100 @after = value
95101 end
96102
@@ -136,9 +142,9 @@ def fetch
136142 has_additional = records_plus_one . size > @page_size
137143
138144 records = records_plus_one . take ( @page_size )
139- records . reverse! unless @is_forward_pagination
145+ records . reverse! unless @forward_pagination
140146
141- if @is_forward_pagination
147+ if @forward_pagination
142148 has_next_page = has_additional
143149 has_previous_page = @current_cursor . present?
144150 else
@@ -301,15 +307,15 @@ def arel_column(column)
301307 end
302308
303309 def pagination_direction ( direction )
304- if @is_forward_pagination
310+ if @forward_pagination
305311 direction
306312 else
307313 direction == :asc ? :desc : :asc
308314 end
309315 end
310316
311317 def pagination_operator ( direction )
312- if @is_forward_pagination
318+ if @forward_pagination
313319 direction == :asc ? :gt : :lt
314320 else
315321 direction == :asc ? :lt : :gt
@@ -318,7 +324,7 @@ def pagination_operator(direction)
318324
319325 def advance_by_page ( page )
320326 @current_cursor =
321- if @is_forward_pagination
327+ if @forward_pagination
322328 page . next_cursor
323329 else
324330 page . previous_cursor
0 commit comments