cartodb/app/controllers/carto/api/paged_searcher.rb
2020-06-15 10:58:47 +08:00

69 lines
2.6 KiB
Ruby

module Carto
module Api
module PagedSearcher
VALID_ORDER_DIRECTIONS = [:asc, :desc].freeze
def page_per_page_params(default_per_page: 20)
page = (params[:page].presence || 1).to_i
unless page > 0
raise Carto::ParamInvalidError.new('page')
end
per_page = (params[:per_page].presence || default_per_page).to_i
unless per_page > 0
raise Carto::ParamInvalidError.new('per_page')
end
[page, per_page]
end
def page_per_page_order_params(valid_order_values, default_per_page: 20, default_order: 'updated_at',
default_order_direction: 'desc', valid_order_combinations: [])
page, per_page = page_per_page_params(default_per_page: default_per_page)
order = extract_param(name: :order, default_value: default_order, valid_values: valid_order_values,
valid_combinations: valid_order_combinations)
order_direction = extract_param(name: :order_direction, default_value: default_order_direction,
valid_values: VALID_ORDER_DIRECTIONS,
valid_combinations: VALID_ORDER_DIRECTIONS)
[page, per_page, order, order_direction]
end
def paged_result(result:, total_count:, page:, per_page:, params:)
last_page = (total_count / per_page.to_f).ceil
link_params = params.merge(per_page: per_page)
metadata = {
total: total_count,
count: result.count,
result: result,
_links: {
first: { href: yield(link_params.merge(page: 1)) },
last: { href: yield(link_params.merge(page: last_page)) }
}
}
metadata[:_links][:prev] = { href: yield(link_params.merge(page: page - 1)) } if page > 1
metadata[:_links][:next] = { href: yield(link_params.merge(page: page + 1)) } if last_page > page
metadata
end
def extract_param(name:, default_value:, valid_values:, valid_combinations:)
param = (params[name].presence || default_value).to_sym
param_values = param.to_s.split(',').map(&:to_sym)
single_parameter = valid_combinations.empty? || param_values.size == 1
if single_parameter && valid_values.exclude?(param)
raise Carto::ParamInvalidError.new(name, valid_values)
end
if !single_parameter && (param_values - valid_combinations).present?
raise Carto::ParamCombinationInvalidError.new(name, valid_combinations)
end
param
end
end
end
end