1 # frozen_string_literal: true
3 module PaginationMethods
4 extend ActiveSupport::Concern
6 Paginator = Struct.new(:items, :newer_items_cursor, :older_items_cursor)
11 # limit selected items to one page, get ids of first item before/after the page
12 def get_page_items(items, includes: [], limit: 20, cursor_column: :id)
13 param! :before, Integer, :min => 0
14 param! :after, Integer, :min => 0
16 qualified_cursor_column = "#{items.table_name}.#{cursor_column}"
17 page_items = if params[:before]
18 items.where("#{qualified_cursor_column} < ?", params[:before]).reorder(cursor_column => :desc)
20 items.where("#{qualified_cursor_column} > ?", params[:after]).reorder(cursor_column => :asc)
22 items.reorder(cursor_column => :desc)
25 page_items = page_items.limit(limit)
26 page_items = page_items.includes(includes)
27 page_items = page_items.sort.reverse
29 newer_items_cursor = page_items.first&.send cursor_column
30 older_items_cursor = page_items.last&.send cursor_column
34 :newer_items_cursor => (newer_items_cursor if page_items.any? && items.exists?(["#{qualified_cursor_column} > ?", newer_items_cursor])),
35 :older_items_cursor => (older_items_cursor if page_items.any? && items.exists?(["#{qualified_cursor_column} < ?", older_items_cursor]))