Pagy is the ultimate pagination gem that outperforms the others in each and every benchmark and comparison.
- This version requires
ruby 3.0+
. Forruby <3.0
usepagy <4.0
(see the pagy3 branch) - Updating
pagy
from3.0+
to4.0+
requires a single renaming in your code, but only if it uses thesearchkick
or theelasticsearch_rails
extras (see the Changelog) - Added the docker development environment to ease contributions
- Big code restyling following ruby 3.0 syntax and cops; tried to make the code simpler, more readable and verbose with almost negligible performance loss.
The best way to quickly get an idea about Pagy is comparing it to the other well known gems.
The values shown in the charts below have been recorded while each gem was producing the exact same output in the exact same environment. (see the Detailed Gems Comparison)
Each dot in the visualization above represents the resources that Pagy consumes for one full rendering. The other gems consume hundreds of times as much for the same rendering.
The IPS/Kb ratio is calculated out of speed (IPS) and Memory (Kb): it shows how well each gem uses each Kb of memory it allocates/consumes.
- Pagy has a very slim core code of just above 100 lines of simple ruby, organized in 3 flat modules, very easy to understand and use (see more...)
- It has a quite fat set of optional extras that you can explicitly require for very efficient and modular customization (see extras)
- It has no dependencies: it produces its own HTML, URLs, i18n with its own specialized and fast code (see why...)
- 100% of its methods are public API, accessible and overridable right where you use them (no pesky monkey-patching needed)
- 100% test coverage for core code and extras
- The
Pagy
class doesn't need to know anything about your models, ORM or storage, so it doesn't add any code to them (see why...) - It works with all kinds of collections, even pre-paginated, records, Arrays, JSON data... and just any list, even if you cannot count it (see how...)
- Pagy works with the most popular Rack frameworks (Rails, Sinatra, Padrino, ecc.) out of the box (see more...)
- It works also with any possible non-Rack environment by just overriding one or two two-lines methods (see more...)
- Pagy is very modular and does not load any unnecessary code in your app (see why...)
- It works even with collections/scopes that already used
limit
andoffset
(see how...) - It works with fast helpers OR easy to edit templates (see more...)
- It raises real
Pagy::OverflowError
exceptions that you can rescue from (see how...) or use the overflow extra for a few ready to use common behaviors - It does not impose any difficult-to-override logic or output (see why...)
After requiring pagy
and including its module(s) (see Quick Start), you can use it in your controller and views:
Paginate your collection in some controller:
@pagy, @records = pagy(Product.some_scope)
Render the navigation links with a super-fast helper in some view:
<%== pagy_nav(@pagy) %>
Or - if you prefer - render the navigation links with a template:
<%== render partial: 'pagy/nav', locals: {pagy: @pagy} %>
However, Pagy goes far beyond the classic pagination above. You can also use fast client-side rendering, headers pagination or integrate it with javascript frameworks (e.g. vue.js
, react
, ...) by just requiring the extras that you need.
Use the official extras, or write your own in just a few lines. Extras add special options and manage different components, behaviors, Frontend or Backend environments... usually by just requiring them:
- arel: Better performance of grouped ActiveRecord collections
- array: Paginate arrays efficiently, avoiding expensive array-wrapping and without overriding
- countless: Paginate without the need of any count, saving one query per rendering
- elasticsearch_rails: Paginate
ElasticsearchRails
response objects - headers: Add RFC-8288 compliant http response headers (and other helpers) useful for API pagination
- metadata: Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc.
- searchkick: Paginate
Searchkick::Results
objects
- bootstrap: Add nav, nav_js and combo_nav_js helpers for the Bootstrap pagination component
- bulma: Add nav, nav_js and combo_nav_js helpers for the Bulma CSS pagination component
- foundation: Add nav, nav_js and combo_nav_js helpers for the Foundation pagination component
- materialize: Add nav, nav_js and combo_nav_js helpers for the Materialize CSS pagination component
- navs: Add nav_js and combo_nav_js unstyled helpers
- semantic: Add nav, nav_js and combo_nav_js helpers for the Semantic UI CSS pagination component
- tailwind: Extra styles for Tailwind CSS
- uikit: Add nav, nav_js and combo_nav_js helpers for the UIkit pagination component
- i18n: Use the
I18n
gem instead of the pagy-i18n implementation - items: Allow the client to request a custom number of items per page with an optional selector UI
- overflow: Allow for easy handling of overflowing pages
- support: Extra support for features like: incremental, auto-incremental and infinite pagination
- trim: Remove the
page=1
param from the first page link
Besides the classic pagination offered by the pagy_nav
helpers, you can use a couple of more performant alternatives:
-
pagy_nav_js: A faster and lighter classic looking UI, rendered on the client side with optional responsiveness:
-
pagy_combo_nav_js: The fastest and lightest alternative UI (48x faster, 48x lighter and 2,270x more efficient than Kaminari) that combines navigation and pagination info in a single compact element:
- pagy-cursor An early stage project that implements cursor pagination for AR
Notice: the pagy_nav_bootstrap
helper used in the screencast has been renamed as pagy_bootstrap_nav
since version 2.0
- Migrating from WillPaginate and Kaminari (practical guide)
- Detailed Gems Comparison (charts and analysis)
- Benchmarks and Memory Profiles Source (Rails app repository)
- Faster Pagination with Pagy introductory tutorial by Sirajus Salekin
- Pagy with Templates Minipost by aloucas
- Pagination with Pagy by Tiago Franco
- Quick guide for Pagy with Sinatra and Sequel by Victor Afanasev
- Integrating Pagy with Hanami by Paweł Świątkowski
- Stateful Tabs with Pagy by Chris Seelus
- Handling Pagination When POSTing Complex Search Forms by Ben Koshy.
- How to Override pagy methods only in specific circumstances by Ben Koshy.
- How to make your pagination links sticky + bounce at the bottom of your page by Ben Koshy.
- 日本語の投稿
- 한국어 튜토리얼
Pagy follows the Semantic Versioning 2.0.0. Please, check the Changelog for breaking changes introduced by mayor versions.
Pull Requests are welcome!
Setting up a development environment for Pagy is very simple if you use the docker environment.
Before spending time creating a (potentially complex) Pull Request, you can Confirm on Gitter whether your proposed changes are going to be useful for most users.
If you Create A Pull Request, please ensure that the "All checks have passed" indicator gets green light on the Pull Request page. That means that the tests passed and Codecov and Rubocop are happy.
The master
branch is the latest rubygem-published release. It also contains docs and comment changes that don't affect the published code.
The dev
branch is the development branch with the new code that will be merged in the next release.
Expect any other branch to be experimental, force-rebased and/or deleted even without merging.
Many thanks to:
- GoRails for the great Pagy Screencast and their top notch Rails Episodes
- Imaginary Cloud for continually publishing high-interest articles and helping to share Pagy when it just started
- JetBrains for their free OpenSource license
- The Contributors for all the smart code and suggestions merged in the project
- The Stargazers for showing their support
This project is available as open source under the terms of the MIT License.