Skip to content

Commit

Permalink
[GEM] Add the pagy_get_count method to the backend
Browse files Browse the repository at this point in the history
  • Loading branch information
ddnexus committed Apr 15, 2024
1 parent ec485d7 commit e2babfb
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 15 deletions.
12 changes: 10 additions & 2 deletions docs/api/backend.md
Expand Up @@ -72,14 +72,22 @@ self contained custom `pagy` method. (see [Writing your own Pagy methods](#writi
Sub-method called only by the `pagy` method, it returns the hash of variables used to initialize the Pagy object.

Override it if you need to add or change some variable. For example you may want to add the `:item_name` in order to customize
the output _(see [How to customize the item name](/docs/how-to.md#customize-the-item-name))_, or even cache the `count`.
the output _(see [How to customize the item name](/docs/how-to.md#customize-the-item-name))_.

!!!warning Don't remove `:count` and `:page`
`:count` and `:page` are the only 2 required Pagy core variables, so be careful not to remove them from the returned hash.
If you override it, remember that `:count` and `:page` are the only 2 required Pagy core variables, so be careful not to remove them from the returned hash.
!!!

See also the [How To](/docs/how-to.md) page for some usage examples.

==- `pagy_get_count(collection, vars)`

Get the count from the collection, considering also the `:count_args` variable. Override it if you need to calculate the count in some specil way, or cache it.

==- `pagy_get_page(vars)`

Get the `page` from the param ,looking at the `:page_param` variable. See also [Customize the page_param](/docs/how-to.md#customize-the-page-param).

==- `pagy_get_items(collection, pagy)`

Sub-method called only by the `pagy` method, it returns the page items (i.e. the records belonging to the current page).
Expand Down
16 changes: 5 additions & 11 deletions docs/how-to.md
Expand Up @@ -178,7 +178,7 @@ collections in the same action. Depending on the scope of the customization, you
2. `pagy(scope, page_param: :custom_param)` or `Pagy.new(count:100, page_param: :custom_param)` will be used for a single
instance (overriding the global default)

You can also override the `pagy_get_vars` if you need some special way to get the page number.
You can also override the [pagy_get_page](/docs/api/backend.md#pagy-get-page-vars) if you need some special way to get the page number.

## Customize the link attributes

Expand Down Expand Up @@ -731,19 +731,13 @@ You have 2 possible solutions in order to improve the performance.
Depending on the nature of the app, a possible cheap solution would be caching the count of the collection, and Pagy makes that
really simple.

Pagy gets the collection count through its `pagy_get_vars` method, so you can override it in your controller. Here is an example
Pagy gets the collection count through its `pagy_get_count` method, so you can override it in your controller. Here is an example
using the rails cache:

```ruby controller
# override the pagy_get_vars method so it will call your cache_count method
def pagy_get_vars(collection, vars)
vars[:count] ||= cache_count(collection)
vars[:page] ||= params[vars[:page_param] || Pagy::DEFAULT[:page_param]]
vars
end

# add Rails.cache wrapper around the count call
def cache_count(collection)
# override the pagy_get_count method adding
# the Rails.cache wrapper around the count call
def pagy_get_count(collection, _vars)
cache_key = "pagy-#{collection.model.name}:#{collection.to_sql}"
Rails.cache.fetch(cache_key, expires_in: 20 * 60) do
collection.count(:all)
Expand Down
9 changes: 7 additions & 2 deletions gem/lib/pagy/backend.rb
Expand Up @@ -18,12 +18,17 @@ def pagy(collection, vars = {})
# You may need to override the count call for non AR collections
def pagy_get_vars(collection, vars)
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
count_args = vars[:count_args] || DEFAULT[:count_args]
vars[:count] ||= (count = collection.count(*count_args)).is_a?(Hash) ? count.size : count
vars[:count] ||= pagy_get_count(collection, vars)
vars[:page] ||= pagy_get_page(vars)
vars
end

# Get the count from the collection
def pagy_get_count(collection, vars)
count_args = vars[:count_args] || DEFAULT[:count_args]
(count = collection.count(*count_args)).is_a?(Hash) ? count.size : count
end

# Get the page integer from the params
# Overridable by the jsonapi extra
def pagy_get_page(vars)
Expand Down

0 comments on commit e2babfb

Please sign in to comment.