Class: Praxis::Extensions::Pagination::PaginationHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/praxis/extensions/pagination/pagination_handler.rb

Defined Under Namespace

Classes: PaginationException

Class Method Summary collapse

Class Method Details

.limit(_query, _limit) ⇒ Object



64
65
66
# File 'lib/praxis/extensions/pagination/pagination_handler.rb', line 64

def self.limit(_query, _limit)
  raise 'implement in derived class'
end

.offset(_query, _offset) ⇒ Object



60
61
62
# File 'lib/praxis/extensions/pagination/pagination_handler.rb', line 60

def self.offset(_query, _offset)
  raise 'implement in derived class'
end

.paginate(query, pagination, root_resource:) ⇒ Object



9
10
11
12
13
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
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/praxis/extensions/pagination/pagination_handler.rb', line 9

def self.paginate(query, pagination, root_resource:)
  return query unless pagination.paginator

  paginator = pagination.paginator

  q = if paginator.page
        offset(query, (paginator.page - 1) * paginator.items)
      else
        # If there is an order clause that complies with the "by" field sorting, we can use it directly
        # i.e., We can be smart about allowing the main sort field matching the pagination one (in case you want to sub-order in a custom way)
        oclause = if pagination.order.nil? || pagination.order.empty? # No ordering specified => use ascending based on the "by" field
                    direction = :asc
                    order(query, [{ asc: paginator.by }], root_resource: root_resource)
                  else
                    first_ordering = pagination.order.items.first
                    direction = first_ordering.keys.first
                    unless first_ordering[direction].to_sym == pagination.paginator.by.to_sym
                      string_clause = pagination.order.items.map do |h|
                        dir, name = h.first
                        "#{name} #{dir}"
                      end.join(',')
                      raise PaginationException,
                            "Ordering clause [#{string_clause}] is incompatible with pagination by field '#{pagination.paginator.by}'. " \
                            "When paginating by a field value, one cannot specify the 'order' clause " \
                            "unless the clause's primary field matches the pagination field."
                    end
                    order(query, pagination.order, root_resource: root_resource)
                  end

        if paginator.from
          if direction == :desc
            where_lt(oclause, paginator.by, paginator.from)
          else
            where_gt(oclause, paginator.by, paginator.from)
          end
        else
          oclause
        end

      end
  limit(q, paginator.items)
end

.where_gt(_query, _attr, _value) ⇒ Object



56
57
58
# File 'lib/praxis/extensions/pagination/pagination_handler.rb', line 56

def self.where_gt(_query, _attr, _value)
  raise 'implement in derived class'
end

.where_lt(_query, _attr, _value) ⇒ Object



52
53
54
# File 'lib/praxis/extensions/pagination/pagination_handler.rb', line 52

def self.where_lt(_query, _attr, _value)
  raise 'implement in derived class'
end