Skip to content

Commit 6eefeea

Browse files
authored
docs: Update docs on default pagination behavior. (#2226)
1 parent 02147e0 commit 6eefeea

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

documentation/topics/advanced/pagination.livemd

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ Ash has built-in support for two kinds of pagination: `offset` and `keyset`. You
1313

1414
Pagination support is configured on a per-action basis. A single action can support both kinds of pagination if desired, but typically you would use one or the other. Read actions generated with `defaults [:read]` support both offset and keyset pagination, for other `read` actions you have to configure the [`pagination` section](https://hexdocs.pm/ash/dsl-ash-resource.html#actions-read-pagination).
1515

16+
> ### Default Pagination Type
17+
>
18+
> When an action supports both pagination types, the behavior depends on your application configuration. See the ["Default Pagination Behavior"](#default-pagination-behavior-when-both-types-are-supported) section below for details on how Ash determines which type to use.
19+
1620
> ### Check the updated query return type!
1721
>
1822
> Pagination will modify the return type of calling the query action.
@@ -895,9 +899,31 @@ last_page.more?
895899
false
896900
```
897901

898-
### Actions supporting both offset and keyset pagination
902+
### Default Pagination Behavior When Both Types Are Supported
903+
904+
When an action supports both `offset` and `keyset` pagination (such as default read actions), Ash uses the following logic to determine which pagination type to use:
905+
906+
**1. Explicit pagination parameters take precedence:**
907+
- If `after` or `before` is provided → keyset pagination
908+
- If `offset` is provided → offset pagination
909+
910+
**2. Configuration-based default for ambiguous cases:**
911+
Ash is configured to use keyset-pagination by default when installed with `mix igniter.install ash`, or the homepage installer.
912+
913+
#### Practical Examples
899914

900-
If an action supports both offset and keyset pagination (e.g. default read actions), offset pagination is used by default when page options only contain `limit`. However, the records will have the keyset in the metadata, so keyset pagination can be performed on next pages.
915+
Regardless of configuration, the records will have keyset metadata, so you can always transition between pagination types:
916+
917+
```elixir
918+
# By default, this uses keyset pagination
919+
%{results: [_, last]} = Ash.read!(Post, page: [limit: 2])
920+
921+
# Explicitly use keyset pagination for the next page
922+
Ash.read!(Post, page: [limit: 2, after: last.__metadata__.keyset])
923+
924+
# Explicitly use offset pagination
925+
Ash.read!(Post, page: [limit: 2, offset: 2])
926+
```
901927

902928
```elixir
903929
%Ash.Page.Offset{results: [_, last]} = Domain.list_posts!(page: [limit: 2])

documentation/topics/development/backwards-compatibility-config.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ config :ash, include_embedded_source_by_default?: false
3333
### Old Behavior
3434

3535
When working with embedded types, the `__source__` constraint is populated with
36-
the original changeset. This can be very costly in terms of memory when working with
36+
the original changeset. This can be very costly in terms of memory when working with
3737
large sets of embedded resources.
3838

3939
### New Behavior
@@ -66,14 +66,16 @@ config :ash, default_page_type: :keyset
6666

6767
### Old Behavior
6868

69-
When an action supports `offset` and `keyset` pagination, and a page is requested
70-
with only `limit` set, i.e `page: [limit: 10]`, you would get back an `%Ash.Page.Offset{}`.
69+
When an action supports both `offset` and `keyset` pagination, and a page is requested
70+
with only `limit` set (i.e., `page: [limit: 10]`), Ash defaulted to offset pagination
71+
and returned an `%Ash.Page.Offset{}`.
7172

7273
### New Behavior
7374

74-
Now we will return a `%Ash.Page.Keyset{}` choosing it whenever it is ambiguous.
75-
You can always force returning an `%Ash.Page.Offset{}` by providing the offset option,
76-
i.e `page: [offset: 0]`
75+
With the current default configuration, Ash will now return an `%Ash.Page.Keyset{}` when the pagination
76+
type is ambiguous (only `limit` is provided).
77+
78+
For detailed pagination behavior documentation, see the [pagination guide](/documentation/topics/advanced/pagination.livemd#default-pagination-behavior-when-both-types-are-supported).
7779

7880
## policies.no_filter_static_forbidden_reads?
7981

@@ -172,15 +174,15 @@ reverse order. This was missed for `Ash.Query`. Meaning if you had something lik
172174

173175
```elixir
174176
read :read do
175-
prepare fn query, _ ->
176-
Ash.Query.after_action(query, fn query, results ->
177+
prepare fn query, _ ->
178+
Ash.Query.after_action(query, fn query, results ->
177179
IO.puts("hook 1")
178180
{:ok, results}
179181
end)
180182
end
181183

182-
prepare fn query, _ ->
183-
Ash.Query.after_action(query, fn query, results ->
184+
prepare fn query, _ ->
185+
Ash.Query.after_action(query, fn query, results ->
184186
IO.puts("hook 2")
185187
{:ok, results}
186188
end)

0 commit comments

Comments
 (0)