Announcing a new gem for cursor-based pagination for ActiveRecord

Announcing a new gem for cursor-based pagination in rails - GitHub - fatkodima/activerecord_cursor_paginate: Cursor-based pagination for ActiveRecord

It is very simple, yet powerful! :muscle:It has the pieces missing in all other gems like iterating by multiple columns, multiple directions, iterating over joins or ordering by custom SQL expressions.

A simple example:

paginator = user.posts.cursor_paginate(limit: 10)
page = paginator.fetch # or `paginator.page` as an alias

page.records # => [#<Post:0x00007fd7071b2ea8 @id=1>, #<Post:0x00007fd7071bb738 @id=2>, ..., #<Post:0x00007fd707238260 @id=10>]
page.count # => 10
page.empty? # => false
page.cursors # => ["MQ==", "Mg==", ..., "MTA="]
page.previous_cursor # => "MQ=="
page.next_cursor  # => "MTA="
page.has_previous? # => false
page.has_next? # => true
4 Likes

Thank you!

Am I understanding correctly that this gem will not work for projects that use UUIDs as primary keys?

Depends on the UUID version. The column to sort by should be sortable. Default (v4) version is not sortable, so you still need to sort by another column.

Currently, the gem implicitly appends a primary column column by default (if it is not explicitly specified), so yeah, that will not work. I think, I will change the gem to not do that for UUIDv4 columns.

The thing I don’t understand is why would we ever want to sort by the primary key column? (Given the fact that it won’t work with UUID primary keys in many cases.)

Why would we not want to (always/by default) sort by .created_at in order to accomplish that goal which seems to be the chronological order?

created_at column values are not unique and when paginating through the records using them, it is possible to skip some records with the same values.

Some people may want to sort by something else, which can also be not unique. So we must append a unique column (the most obvious choice is a primary key) to avoid these problems. So the sorting will be by created_at, id.

1 Like

Added a knob to disable implicitly appending the primary key to a list of sorting columns.

Ha, interesting!

I just recently wrote about how I implemented my own simple cursor pagination.

My main thing was it needed to work well with turbo for infinite pagination, so it’s even simpler. Not even worth extracting to a gem :see_no_evil: