# frozen_string_literal: true # Методы фильтрации сортировки и паджинации # rubocop:disable Metrics/CyclomaticComplexity # rubocop:disable Metrics/PerceivedComplexity module FilterSortPagination extend ActiveSupport::Concern included do prepend_after_action :set_filter_headers # Установить(добавить) информацию о пагинации в заголовок ответа # # @param [String, Symbol] collection_name имя переменной в которой хранится коллекция # @param [Hash] options дополнительные параметры для колбека def self.set_pagination_headers(collection_name, options = {}) after_action(options) do |_controller| if params[:page].present? collection = instance_variable_get("@#{collection_name}") request_params = request.query_parameters unless request_params.empty? url_without_params = request.original_url.slice(0..(request.original_url.index("?") - 1)) end url_without_params ||= request.original_url page = {} if collection.total_pages > 1 && !collection.first_page? page[:first] = 1 end if collection.total_pages > 1 && !collection.last_page? page[:last] = collection.total_pages end page[:next] = collection.current_page + 1 unless collection.last_page? unless collection.first_page? page[:prev] = collection.current_page - 1 end pagination_links = [] page.each do |k, v| new_request_hash = request_params.merge(page: v) pagination_links << "<#{url_without_params}?#{new_request_hash.to_param}>; rel=\"#{k}\"" end headers["Link"] = pagination_links.join(", ") headers["X-Pagination-Count"] = collection.total_count headers["X-Pagination-Page"] = collection.current_page headers["X-Pagination-Limit"] = collection.limit_value # TODO : удалить после того как UI переделают под новый формат заголовка # headers["X-Pagination"] = { limit: collection.limit_value, total_pages: collection.total_pages, prev_page: collection.prev_page, current_page: collection.current_page, next_page: collection.next_page, first_page: collection.first_page?, last_page: collection.last_page?, out_of_range: collection.out_of_range?, }.to_json end end end # Optional query parameters # # - limit ограничение количества записей в выборке # (пример: ?limit=5) # # - page номер страницы(по умолчанию 15 записей на одну страницу) # (пример: ?page=1) # # - sort сортировка, указывается поле и порядок сортировки # (пример: ?sort=created_asc) # # - search поиск по совпадению с частью вводимого значения # (пример: ?search=wat_name_part) # # - name поиск по совпадению с частью вводимого значения(search alias) # (пример: ?name=wat_name_part) # def filter_params params.permit(:page, :limit, :sort, :search, :name).to_h end def set_filter_headers if filter_params[:search].present? headers["X-Search"] = filter_params[:search] end if filter_params[:sort].present? headers["X-Sort"] = filter_params[:sort] end end end end # rubocop:enable Metrics/CyclomaticComplexity # rubocop:enable Metrics/PerceivedComplexity