FedeMadoery
How to use Pagination on Calculations? Do I need to handcraft my own Pagination macro?
I’m trying to do a pagination for a list of “messages” on a calculated field, so my structure is more or like the following one:
Channel Resource
defmodule Organizations.Channel do
use Ash.Resource,
data_layer: AshPostgres.DataLayer,
extensions: [
AshGraphql.Resource
]
require Ash.Query
# Some other configs ...
relationships do
has_many :messages, Channels.ChannelMessage do
private? true
destination_attribute :channel_id
api Channels
end
actions do
defaults [:create, :update, :destroy]
# This one creates a PageOfChannels
read :list do
pagination countable: true,
required?: true,
offset?: true,
max_page_size: 10
end
read :read do
primary? true
end
end
Channel Messages Resource
defmodule Channels.ChannelMessage do
use Ash.Resource,
data_layer: AshPostgres.DataLayer,
extensions: [
AshGraphql.Resource
]
# Some other configs ...
actions do
# This creates a PageOfChannelMessages
read :list do
pagination countable: true,
required?: true,
offset?: true,
max_page_size: 10,
default_limit: 10
end
read :read do
primary? true
end
end
relationships do
belongs_to :channel, Channels.Channel do
allow_nil? false
primary_key? true
end
end
With that said, I want to access my ChannelMessages, from the Channel resource, so I added a calculation for it, but I also want to paginate them using the same Type and structure (in this case PageOfChannelMessages) to share entities on the UI side with ApolloClient
So I did:
calculations do
calculate :channel_messages, {:array, ChannelMessageUnion}, fn record, %{api: api} ->
record = api.load!(record, :messages)
record.messages
|> Enum.map(&%Ash.Union{type: ChannelMessageUnion.struct_to_name(&1), value: &1})
end
But with this calculation, my channel_messages is just an array with all the messages or just a trimmed array if I limit it, so I don’t see how I can calculate as a PageOf type since those types are not accessible or I don’t know how, so with this in mind, my question would be can I reuse the actual pagination of AshGraphQL o should I cook my own pagination to be able to re-use it across all my app (calculation and lists)
Marked As Solved
juno
Wow. it’s working now. Awesome!
Looks like, in the module-based calculation, the return type must be a list of items. We got it to work with an inline calculation anonymous function. I see that there is a ticket for this specific issue in ash git repo Anonymous function calculations are inconsistent with module calculations · Issue #625 · ash-project/ash · GitHub
calculate :channel_messages, MyApp.PageOfChannelMessages, fn record,
%{
offset: offset,
limit: limit
} = context ->
...Do your thing here
{:ok, %{Page Of Channel Message info}
end do
argument :offset, :integer do
default 0
end
argument :limit, :integer do
default 10
end
end
I can’t thank you enough for helping us out.
Also Liked
FedeMadoery
Wow, thanks so much for the fast response…
I will give it a try and post the final result if it works or some other question if I get stuck! Thanks so much
zachdaniel
I should really reproduce this in a test. However, I believe I’ve isolated the fix. Please try out ash_graphql main.
juno
Last Post!
juno
Popular in Questions
Other popular topics
Latest Ash Threads
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #hex
- #security









