Commit cc1d1411 authored by Andreas Brandl's avatar Andreas Brandl

Refactor and extract DefaultPaginationStrategy.

parent 7e78eacd
...@@ -2,67 +2,80 @@ module API ...@@ -2,67 +2,80 @@ module API
module Helpers module Helpers
module Pagination module Pagination
def paginate(relation) def paginate(relation)
relation = add_default_order(relation) DefaultPaginationStrategy.new(self).paginate(relation)
relation.page(params[:page]).per(params[:per_page]).tap do |data|
add_pagination_headers(data)
end
end end
private class DefaultPaginationStrategy
attr_reader :ctx
delegate :params, :header, :request, to: :ctx
def add_pagination_headers(paginated_data) def initialize(ctx)
header 'X-Per-Page', paginated_data.limit_value.to_s @ctx = ctx
header 'X-Page', paginated_data.current_page.to_s end
header 'X-Next-Page', paginated_data.next_page.to_s
header 'X-Prev-Page', paginated_data.prev_page.to_s
header 'Link', pagination_links(paginated_data)
return if data_without_counts?(paginated_data) def paginate(relation)
relation = add_default_order(relation)
header 'X-Total', paginated_data.total_count.to_s relation.page(params[:page]).per(params[:per_page]).tap do |data|
header 'X-Total-Pages', total_pages(paginated_data).to_s add_pagination_headers(data)
end end
end
def pagination_links(paginated_data) private
request_url = request.url.split('?').first
request_params = params.clone
request_params[:per_page] = paginated_data.limit_value
links = [] def add_default_order(relation)
if relation.is_a?(ActiveRecord::Relation) && relation.order_values.empty?
relation = relation.order(:id)
end
request_params[:page] = paginated_data.prev_page relation
links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") if request_params[:page] end
request_params[:page] = paginated_data.next_page def add_pagination_headers(paginated_data)
links << %(<#{request_url}?#{request_params.to_query}>; rel="next") if request_params[:page] header 'X-Per-Page', paginated_data.limit_value.to_s
header 'X-Page', paginated_data.current_page.to_s
header 'X-Next-Page', paginated_data.next_page.to_s
header 'X-Prev-Page', paginated_data.prev_page.to_s
header 'Link', pagination_links(paginated_data)
request_params[:page] = 1 return if data_without_counts?(paginated_data)
links << %(<#{request_url}?#{request_params.to_query}>; rel="first")
unless data_without_counts?(paginated_data) header 'X-Total', paginated_data.total_count.to_s
request_params[:page] = total_pages(paginated_data) header 'X-Total-Pages', total_pages(paginated_data).to_s
links << %(<#{request_url}?#{request_params.to_query}>; rel="last")
end end
links.join(', ') def pagination_links(paginated_data)
end request_url = request.url.split('?').first
request_params = params.clone
request_params[:per_page] = paginated_data.limit_value
def total_pages(paginated_data) links = []
# Ensure there is in total at least 1 page
[paginated_data.total_pages, 1].max
end
def add_default_order(relation) request_params[:page] = paginated_data.prev_page
if relation.is_a?(ActiveRecord::Relation) && relation.order_values.empty? links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") if request_params[:page]
relation = relation.order(:id)
request_params[:page] = paginated_data.next_page
links << %(<#{request_url}?#{request_params.to_query}>; rel="next") if request_params[:page]
request_params[:page] = 1
links << %(<#{request_url}?#{request_params.to_query}>; rel="first")
unless data_without_counts?(paginated_data)
request_params[:page] = total_pages(paginated_data)
links << %(<#{request_url}?#{request_params.to_query}>; rel="last")
end
links.join(', ')
end end
relation def total_pages(paginated_data)
end # Ensure there is in total at least 1 page
[paginated_data.total_pages, 1].max
end
def data_without_counts?(paginated_data) def data_without_counts?(paginated_data)
paginated_data.is_a?(Kaminari::PaginatableWithoutCount) paginated_data.is_a?(Kaminari::PaginatableWithoutCount)
end
end end
end end
end end
......
...@@ -17,8 +17,6 @@ module Gitlab ...@@ -17,8 +17,6 @@ module Gitlab
end end
end end
private
# Methods needed by `API::Helpers::Pagination` # Methods needed by `API::Helpers::Pagination`
# #
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment