Class: Praxis::Extensions::Pagination::PaginationParams::DSLCompiler

Inherits:
Attributor::DSLCompiler
  • Object
show all
Defined in:
lib/praxis/extensions/pagination/pagination_params.rb

Overview

DSL for definition pagination parameters in a defined filter. Available options are:

One can limit which fields the pagination (by cursor) can be allowed. Typically only indexed fields should be allowed for performance reasons:

* by_fields <Array of field names>  (if not provided, all fields are allowed)

One can limit the total maximum of items of the requested page size from the client can ask for:

* max_items <integer> (there is a static upper limit to thie value set by the MAX_ITEMS constant)

One can set the default amount of items to return when not specified by the client

* page_size <integer> (less or equal than max_items, if the max is set)

One can expicitly disallow either paging or cursor based pagination (by default both are allowed)

  • disallow :paging | :cursor

One can set the default pagination mode when no :page, :by/:from parameters are passed in.

  • default <mode>: <value> where mode can be :page or :by (and the value is an integer or a field name respectively)

Here’s a full example: attribute :pagination, Types::PaginationParams.for(MediaTypes::Book) do

by_fields :id, :name
max_items 500
page_size 50
disallow :paging
default by: :id

end

Instance Method Summary collapse

Instance Method Details

#by_fields(*fields) ⇒ Object



58
59
60
61
62
63
64
65
66
67
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 58

def by_fields(*fields)
  requested = fields.map(&:to_sym)
  non_matching = requested - target.media_type.attributes.keys
  unless non_matching.empty?
    raise "Error, you've requested to paginate by fields that do not exist in the mediatype!\n" \
    "The following #{non_matching.size} field/s do not exist in media type #{target.media_type.name} :\n" +
          non_matching.join(',').to_s
  end
  target.fields_allowed = requested
end

#default(spec) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 91

def default(spec)
  unless spec.is_a?(::Hash) && spec.keys.size == 1 && %i[by page].include?(spec.keys.first)
    raise "'default' syntax for pagination takes exactly one key specification. Either by: <:fieldname> or page: <num>" \
          "#{spec} is invalid"
  end
  mode, value = spec.first
  def_mode = case mode
             when :by
               raise "Error setting default pagination. Field #{value} is not amongst the allowed fields." if target.fields_allowed && !target.fields_allowed&.include?(value)
               raise 'Cannot define a default pagination that is cursor based, if cursor-based pagination is disallowed.' if target.defaults[:disallow_cursor]

               { by: value }
             when :page
               raise "Error setting default pagination. Initial page should be a integer (but got #{value})" unless value.is_a?(::Integer)
               raise 'Cannot define a default pagination that is page-based, if page-based pagination is disallowed.' if target.defaults[:disallow_paging]

               { page: value }
             end
  target.defaults[:default_mode] = def_mode
end

#disallow(pagination_type) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 77

def disallow(pagination_type)
  default_mode, default_value = target.defaults[:default_mode].first
  case pagination_type
  when :paging
    raise "Cannot disallow page-based pagination if you define a default pagination of:  page: #{default_value}" if default_mode == :page

    target.defaults[:disallow_paging] = true
  when :cursor
    raise "Cannot disallow cursor-based pagination if you define a default pagination of:   by: #{default_value}" if default_mode == :by

    target.defaults[:disallow_cursor] = true
  end
end

#max_items(max) ⇒ Object



69
70
71
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 69

def max_items(max)
  target.defaults[:max_items] = Integer(max)
end

#page_size(size) ⇒ Object



73
74
75
# File 'lib/praxis/extensions/pagination/pagination_params.rb', line 73

def page_size(size)
  target.defaults[:page_size] = Integer(size)
end