]> git.openstreetmap.org Git - rails.git/blob - app/controllers/concerns/pagination_methods.rb
Merge pull request #6394 from openstreetmap/dependabot/github_actions/ruby/setup...
[rails.git] / app / controllers / concerns / pagination_methods.rb
1 # frozen_string_literal: true
2
3 module PaginationMethods
4   extend ActiveSupport::Concern
5
6   private
7
8   ##
9   # limit selected items to one page, get ids of first item before/after the page
10   def get_page_items(items, includes: [], limit: 20, cursor_column: :id)
11     param! :before, Integer, :min => 0
12     param! :after, Integer, :min => 0
13
14     qualified_cursor_column = "#{items.table_name}.#{cursor_column}"
15     page_items = if params[:before]
16                    items.where("#{qualified_cursor_column} < ?", params[:before]).reorder(cursor_column => :desc)
17                  elsif params[:after]
18                    items.where("#{qualified_cursor_column} > ?", params[:after]).reorder(cursor_column => :asc)
19                  else
20                    items.reorder(cursor_column => :desc)
21                  end
22
23     page_items = page_items.limit(limit)
24     page_items = page_items.includes(includes)
25     page_items = page_items.sort.reverse
26
27     newer_items_cursor = page_items.first&.send cursor_column
28     older_items_cursor = page_items.last&.send cursor_column
29
30     [
31       page_items,
32       (newer_items_cursor if page_items.any? && items.exists?(["#{qualified_cursor_column} > ?", newer_items_cursor])),
33       (older_items_cursor if page_items.any? && items.exists?(["#{qualified_cursor_column} < ?", older_items_cursor]))
34     ]
35   end
36 end