mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 05:23:03 +12:00
docs: update docs, add some context, remove dead link
This commit is contained in:
parent
a66a487cf8
commit
6e43784535
3 changed files with 44 additions and 16 deletions
|
@ -4,7 +4,7 @@ Pagination is configured at the action level. There are two kinds of pagination
|
|||
pros and cons to each. An action can support both at the same time, or only one (or none). A full count of records can be
|
||||
requested by passing `page: [count: true]`, but it should be kept in mind that doing this requires running the same query
|
||||
twice, one of which is a count of all records. Ash does these in parallel, but it can still be quite expensive on large
|
||||
datasets. For more information on the options for configuring actions to support pagination, see the [pagination section](Ash.Resource.Dsl.html#module-pagination) in `Ash.Resource.Dsl`.
|
||||
datasets. For more information on the options for configuring actions to support pagination, see the {{link:ash:dsl:resource/actions/read/prepare}}
|
||||
|
||||
## Offset Pagination
|
||||
|
||||
|
@ -28,8 +28,8 @@ Api.read(Resource, page: [limit: 10, offset: 10])
|
|||
|
||||
### Offset Cons
|
||||
|
||||
- Does not perform well on large datasets
|
||||
- When moving between pages, if data was created or deleted, records may appear on multiple pages or be skipped
|
||||
- Does not perform well on large datasets (if you have to ask if your dataset is "large", it probably isn't)
|
||||
- When moving between pages, if data was created or deleted, records may appear on multiple pages
|
||||
|
||||
## Keyset Pagination
|
||||
|
||||
|
@ -49,11 +49,6 @@ last_record = List.last(page.results)
|
|||
next_page = Api.read(Resource, page: [limit: 10, after: last_record.__metadata__.keyset])
|
||||
```
|
||||
|
||||
### Important Limitation
|
||||
|
||||
Keyset pagination cannot currently be used in conjunction with aggregate and calculation sorting.
|
||||
Combining them will result in an error on the query.
|
||||
|
||||
### Keyset Pros
|
||||
|
||||
- Performs very well on large datasets (assuming indices exist on the columns being sorted on)
|
||||
|
@ -61,10 +56,5 @@ Combining them will result in an error on the query.
|
|||
|
||||
### Keyset Cons
|
||||
|
||||
- A bit more complex
|
||||
- A bit more complex to use
|
||||
- Can't go to a specific page number
|
||||
- Can't use aggregate and calculation sorting (at the moment, this will change soon)
|
||||
|
||||
For more information on keyset vs offset based pagination, see:
|
||||
|
||||
- [Offset vs Seek Pagination](https://taylorbrazelton.com/posts/2019/03/offset-vs-seek-pagination/)
|
||||
|
|
|
@ -117,7 +117,45 @@ Keep in mind that, for create actions, many `expr/1` checks won't make sense, an
|
|||
|
||||
#### Using exists
|
||||
|
||||
In these and in other filter checks, it is advised to use `exists/2` when referring to relationships, because of the way that the policy authorizer may mix & match your policies when building filters. There is a semantic difference in filters between `friends.first_name == "ted" and friends.last_name == "dansen"`. This means that you have a *single* friend with the first_name "bob" and the last name "fred". If you use `exists`, then your policies can be used in filters without excluding unnecessary data, i.e `exists(friends, first_name == "ted") and exists(friends, last_name == "dansen")` means "you have one friend with the first_name "ted" and one friend with the last_name "dansen".
|
||||
Lets compare the following expressions:
|
||||
|
||||
Filtering on related data by directly referencing the relationship
|
||||
```elixir
|
||||
friends.first_name == "ted" and friends.last_name == "dansen"
|
||||
```
|
||||
|
||||
Filtering on related data using `exists/2`
|
||||
|
||||
```elixir
|
||||
exists(friends, first_name == "ted") and exists(friends, last_name == "dansen")
|
||||
```
|
||||
|
||||
In policies (and often any time you mean "a related thing exists where some condition is true") you should generally prefer filter checks, it is advised to use `exists/2` when referring to relationships, because of the way that the policy authorizer may mix & match your policies when building filters. This is also true when adding filters to actions. If you use `exists`, then your policies can be used in filters without excluding unnecessary data, i.e `exists(friends, first_name == "ted") and exists(friends, last_name == "dansen")` means "you have one friend with the first_name "ted" and one friend with the last_name "dansen". For instance, imagine a scenario where you have an action like this:
|
||||
|
||||
```elixir
|
||||
read :friends_of_ted do
|
||||
filter expr(friends.first_name == "ted")
|
||||
end
|
||||
```
|
||||
|
||||
And someone calls it like so:
|
||||
```elixir
|
||||
Resource
|
||||
|> Ash.Query.for_read(:friends_of_ted)
|
||||
|> Ash.Query.filter(friends.last_name == "dansen")
|
||||
```
|
||||
|
||||
The resulting filter is `friends.first_name == "ted" and friends.last_name == "dansen"`. This means that there must be one friend with the name "ted dansen". Sometimes that *is* what you mean to do, but generally speaking I would expect the above code to say "friends of ted that also have a friend with the last name `"dansen"`". To accomplish that, we can rework the example like so:
|
||||
```elixir
|
||||
read :friends_of_ted do
|
||||
filter expr(exists(friends, first_name == "ted"))
|
||||
end
|
||||
|
||||
# Calling it
|
||||
Resource
|
||||
|> Ash.Query.for_read(:friends_of_ted)
|
||||
|> Ash.Query.filter(exists(friends, last_name == "dansen"))
|
||||
```
|
||||
|
||||
#### How expressions are used
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ prefix "user"
|
|||
publish :create, ["created", :user_id]
|
||||
```
|
||||
|
||||
This might publish a message to \"user:created:1\"" for example.
|
||||
This might publish a message to "user:created:1" for example.
|
||||
|
||||
For updates, if the field in the template is being changed, a message is sent
|
||||
to *both* values. So if you change `user 1` to `user 2`, the same message would
|
||||
|
|
Loading…
Reference in a new issue