I'm using active_model_serializer. Now I want to serialize an object with pagination, should I do the pagination logic in the controller or in the serializer?
If I choose to do the pagination in serializer, I need to pass the page_number and per_page to the serializer. How should I do that? My understanding is serializer only takes the model object.
Regular serializers are only concerned with single items - not paginated lists. The most straight forward way to add pagination is in the controller:
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
}
However, this is pretty tedious if you need pagination logic for multiple objects. Looking through the documentation for active_model_serializers you'll come across an ArraySerializer
for serializing an array of objects. What I did was create pagination_serializer.rb
using ArraySerializer
to automatically add the meta tag for paginated arrays:
# 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
Once you have PaginationSerializer
added to your rails app, you simple need to call it when you need pagination meta tags from your controller:
customers = Customer.page(params[:page])
respond_with customers, serializer: PaginationSerializer
Note: I wrote this to use Kaminari as the paginator. However, it can easily be modified to work with any pagination gem or custom solution.