Module: Eluvia::PaginationHandler
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/eluvia/handlers/pagination_handler.rb
Constant Summary collapse
- NOT_SET =
Sentinel distinguishing an unset
max_limit:kwarg (defer topagination_max_limit) from an explicitmax_limit: nil(no ceiling for this call only, regardless of the config/method). Object.new.freeze
Class Method Summary collapse
-
.order_by_param_name ⇒ Object
Resolves the query parameter name carrying the
order_byinput according to the configured API case.
Instance Method Summary collapse
-
#pagination_max_limit ⇒ Object
Ceiling applied to
limitfor this controller. - #set_pagination(default_limit: 20, default_offset: 0, default_order_by: 'created_at:asc', fallback_order_by: 'created_at:asc', force_order_by: false, max_limit: NOT_SET, disable_errors: nil, allow_meta_only_limit: true) ⇒ Object
Class Method Details
.order_by_param_name ⇒ Object
Resolves the query parameter name carrying the order_by input according to the configured
API case. Exposed so callers outside this concern (e.g. request-level validators run in a
before_action ahead of set_pagination) parse the exact same parameter, instead of
duplicating this ternary and risking it drifting out of sync with Config.api_case.
9 10 11 |
# File 'lib/eluvia/handlers/pagination_handler.rb', line 9 def self.order_by_param_name Eluvia::Base::Config.api_case == 'camel_case' ? :orderBy : :order_by end |
Instance Method Details
#pagination_max_limit ⇒ Object
Ceiling applied to limit for this controller. Override to customize (e.g. a
per-resource value pulled from a resource definition). Defaults to the library-wide config.
19 20 21 |
# File 'lib/eluvia/handlers/pagination_handler.rb', line 19 def pagination_max_limit Eluvia::Base::Config.max_page_limit end |
#set_pagination(default_limit: 20, default_offset: 0, default_order_by: 'created_at:asc', fallback_order_by: 'created_at:asc', force_order_by: false, max_limit: NOT_SET, disable_errors: nil, allow_meta_only_limit: true) ⇒ Object
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/eluvia/handlers/pagination_handler.rb', line 23 def set_pagination(default_limit: 20, default_offset: 0, default_order_by: 'created_at:asc', fallback_order_by: 'created_at:asc', force_order_by: false, max_limit: NOT_SET, disable_errors: nil, allow_meta_only_limit: true) # Pagination @limit = resolve_pagination_limit(default_limit: default_limit, max_limit: max_limit, disable_errors: disable_errors, allow_meta_only_limit: ) @offset = params[:offset] ? params[:offset].to_i : default_offset if @limit.zero? # Meta-only request (see `allow_meta_only_limit:`) - no records to page through. @page = 1 @padding = 0 else @page = (@offset / @limit) + 1 @padding = @offset % @limit end # Order by order_by_param = Eluvia::PaginationHandler.order_by_param_name user_order_by = params[order_by_param].to_s.strip # A blank `order_by` is treated as "not supplied" (falls through to defaults/fallback) # rather than as a literal empty ordering, since a Kaminari scope always needs some order. order_by = !force_order_by && user_order_by.present? ? user_order_by : default_order_by order_by = "#{order_by},#{fallback_order_by}" @order_by = {} order_by.split(',').each do |entry| entry = entry.strip # `-1` keeps a trailing empty segment (e.g. `name:`) instead of Ruby's default of # dropping it, so it is caught below as an invalid direction rather than as a bare field. parts = entry.split(':', -1) field_name, direction = parts if parts.length != 2 || field_name.blank? raise Eluvia::Errors::UnprocessableEntity.new({ 'order_by' => I18n.t('eluvia.errors.ordering.invalid_format', default: 'Invalid format, expected "field_name:asc" or "field_name:desc".') }) end unless %w[asc desc].include?(direction) raise Eluvia::Errors::UnprocessableEntity.new({ "order_by__#{field_name}" => I18n.t('eluvia.errors.ordering.invalid_direction', default: 'Invalid order direction. Allowed values are `asc` and `desc`.') }) end @order_by[field_name] = direction.to_sym end end |