Rails active_model_serializer с разбиением на страницы

Я использую active_model_serializer. Теперь я хочу сериализовать объект с разбиением на страницы, должен ли я делать логику разбиения на страницы в контроллере или в сериализаторе?

Если я захочу сделать разбиение на страницы в сериализаторе, мне нужно передать page_number и per_page в сериализатор. Как мне это сделать? Мое понимание сериализатора принимает только объект модели.

Ответ 1

Одноразовое решение

Регулярные сериализаторы занимаются только отдельными элементами - не разбитыми на страницы списками. Самый простой способ добавить разбиение на страницы - в контроллере:

customers = Customer.page(params[:page])
respond_with customers, meta: {
  current_page: customers.current_page,
  next_page: customers.next_page,
  prev_page: customers.prev_page,
  total_pages: customers.total_pages,
  total_count: customers.total_count
}

Многоразовое решение

Однако это довольно утомительно, если вам нужна логика разбиения на страницы для нескольких объектов. Просмотрев документацию для active_model_serializers, вы встретите ArraySerializer для сериализации массива объектов. То, что я сделал, это создать pagination_serializer.rb с помощью ArraySerializer, чтобы автоматически добавить метатег для разбитых на страницы массивов:

# my_app/app/serializers/pagination_serializer.rb
class PaginationSerializer < ActiveModel::Serializer::ArraySerializer
  def initialize(object, options={})
    meta_key = options[:meta_key] || :meta
    options[meta_key] ||= {}
    options[meta_key][:pagination] = {
      current_page: object.current_page,
      next_page: object.next_page,
      prev_page: object.prev_page,
      total_pages: object.total_pages,
      total_count: object.total_count
    }
    super(object, options)
  end
end

Как только вы добавили PaginationSerializer в ваше приложение rails, вам просто нужно вызвать его, когда вам нужны метатеги для разбивки на страницы с вашего контроллера:

customers = Customer.page(params[:page])
respond_with customers, serializer: PaginationSerializer

Примечание. Я написал это, чтобы использовать Kaminari как paginator. Однако его можно легко модифицировать для работы с любым драгоценным камнем или специальным решением.