-
Notifications
You must be signed in to change notification settings - Fork 21
Description
Right now, to use the pagination in a Rails project, we have to write something like this in the controller:
def index
@posts = Post.all
paginated_posts =
RailsCursorPagination::Paginator
.new(first: params[:first],
before: params[:before],
last: params[:last],
after: params[:after])
.fetch(with_total: params[:return_total])
render json: paginated_posts
endAnd this is without even supporting custom ordering. This is quite cumbersome, can lead to a lot of duplicated code, and therefore is also a source of potential bugs.
What we did in our project is to then add a helper method to our ApplicationController like so:
class ApplicationController < ActionController::API
[...]
private
# Convenience method to paginate records with the RailsCursorPagination
# gem and passing in the right parameter values.
#
# @param [ActiveRecord::Relation] records
# @return [Hash]
def paginate(records)
RailsCursorPagination::Paginator
.new(records,
first: params[:first]&.to_i,
after: params[:after],
last: params[:last]&.to_i,
before: params[:before])
.fetch(with_total: ActiveModel::Type::Boolean.new.cast(params[:return_total]))
end
endthis then allows our controllers to be as simple as
def index
@posts = Post.all
render json: paginate(@posts)
endIt would be great if such a method would be directly provided by the gem so that any client can make use of it. It could e.g. be part of a concern that a user can load into their controllers or directly include in their ApplicationController to have it available on all controllers.
We would also have to consider how to allow users to add ordering to this. But this should probably be an opt-in and maybe only allowing ordering on selected columns to avoid performance issues from API users that order on un-optimized columns. I could imagine an interface similar to:
paginate(@posts, allow_ordering: true, restrict_order_to: %i[id author])