From cc1d141127e1f3fa4f3e454460df3238cd062417 Mon Sep 17 00:00:00 2001 From: Andreas Brandl Date: Wed, 25 Apr 2018 15:19:55 +0200 Subject: [PATCH] Refactor and extract DefaultPaginationStrategy. --- lib/api/helpers/pagination.rb | 117 +++++++++++++++------------- lib/gitlab/serializer/pagination.rb | 2 - 2 files changed, 65 insertions(+), 54 deletions(-) diff --git a/lib/api/helpers/pagination.rb b/lib/api/helpers/pagination.rb index 09805049169..cf9501c31fe 100644 --- a/lib/api/helpers/pagination.rb +++ b/lib/api/helpers/pagination.rb @@ -2,67 +2,80 @@ module API module Helpers module Pagination def paginate(relation) - relation = add_default_order(relation) - - relation.page(params[:page]).per(params[:per_page]).tap do |data| - add_pagination_headers(data) - end + DefaultPaginationStrategy.new(self).paginate(relation) end - private + class DefaultPaginationStrategy + attr_reader :ctx + delegate :params, :header, :request, to: :ctx - def add_pagination_headers(paginated_data) - 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) - - return if data_without_counts?(paginated_data) - - header 'X-Total', paginated_data.total_count.to_s - header 'X-Total-Pages', total_pages(paginated_data).to_s - end - - def pagination_links(paginated_data) - request_url = request.url.split('?').first - request_params = params.clone - request_params[:per_page] = paginated_data.limit_value - - links = [] - - request_params[:page] = paginated_data.prev_page - links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") if request_params[:page] - - 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") + def initialize(ctx) + @ctx = ctx end - links.join(', ') - end + def paginate(relation) + relation = add_default_order(relation) - def total_pages(paginated_data) - # Ensure there is in total at least 1 page - [paginated_data.total_pages, 1].max - end - - def add_default_order(relation) - if relation.is_a?(ActiveRecord::Relation) && relation.order_values.empty? - relation = relation.order(:id) + relation.page(params[:page]).per(params[:per_page]).tap do |data| + add_pagination_headers(data) + end end - relation - end + private - def data_without_counts?(paginated_data) - paginated_data.is_a?(Kaminari::PaginatableWithoutCount) + def add_default_order(relation) + if relation.is_a?(ActiveRecord::Relation) && relation.order_values.empty? + relation = relation.order(:id) + end + + relation + end + + def add_pagination_headers(paginated_data) + 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) + + return if data_without_counts?(paginated_data) + + header 'X-Total', paginated_data.total_count.to_s + header 'X-Total-Pages', total_pages(paginated_data).to_s + end + + def pagination_links(paginated_data) + request_url = request.url.split('?').first + request_params = params.clone + request_params[:per_page] = paginated_data.limit_value + + links = [] + + request_params[:page] = paginated_data.prev_page + links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") if request_params[:page] + + 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 + + def total_pages(paginated_data) + # Ensure there is in total at least 1 page + [paginated_data.total_pages, 1].max + end + + def data_without_counts?(paginated_data) + paginated_data.is_a?(Kaminari::PaginatableWithoutCount) + end end end end diff --git a/lib/gitlab/serializer/pagination.rb b/lib/gitlab/serializer/pagination.rb index 9c92b83dddc..6bb00d8ae21 100644 --- a/lib/gitlab/serializer/pagination.rb +++ b/lib/gitlab/serializer/pagination.rb @@ -17,8 +17,6 @@ module Gitlab end end - private - # Methods needed by `API::Helpers::Pagination` #