lib/active_model_serializers/adapter/json_api/pagination_links.rb
# frozen_string_literal: true
module ActiveModelSerializers
module Adapter
class JsonApi < Base
class PaginationLinks
MissingSerializationContextError = Class.new(KeyError)
FIRST_PAGE = 1
attr_reader :collection, :context
def initialize(collection, adapter_options)
@collection = collection
@adapter_options = adapter_options
@context = adapter_options.fetch(:serialization_context) do
fail MissingSerializationContextError, <<-EOF.freeze
JsonApi::PaginationLinks requires a ActiveModelSerializers::SerializationContext.
Please pass a ':serialization_context' option or
override CollectionSerializer#paginated? to return 'false'.
EOF
end
end
def as_json
{
self: location_url,
first: first_page_url,
prev: prev_page_url,
next: next_page_url,
last: last_page_url
}
end
protected
attr_reader :adapter_options
private
def location_url
url_for_page(collection.current_page)
end
def first_page_url
url_for_page(1)
end
def last_page_url
if collection.total_pages == 0
url_for_page(FIRST_PAGE)
else
url_for_page(collection.total_pages)
end
end
def prev_page_url
return nil if collection.current_page == FIRST_PAGE
if collection.current_page > collection.total_pages
return url_for_page(collection.total_pages)
end
url_for_page(collection.current_page - FIRST_PAGE)
end
def next_page_url
return nil if collection.total_pages == 0 ||
collection.current_page >= collection.total_pages
url_for_page(collection.next_page)
end
def url_for_page(number)
params = query_parameters.dup
params[:page] = { size: per_page, number: number }
"#{url(adapter_options)}?#{params.to_query}"
end
def url(options = {})
@url ||= options.fetch(:links, {}).fetch(:self, nil) || request_url
end
def request_url
@request_url ||= context.request_url
end
def query_parameters
@query_parameters ||= context.query_parameters
end
def per_page
@per_page ||= collection.try(:per_page) || collection.try(:limit_value) || collection.size
end
end
end
end
end