How would one go about concatenating strings from a specific attribute on a related embedded resource?
The specific scenario is a resource called Event
that has an embedded array of Attendee
s which in turn has a name
attribute.
Event
:
attribute :attendees, {:array, MyApp.MyDomainSoon.NaturalPerson}, allow_nil?: true
I started out with this just to get the data to concatenate but ran into trouble immediately.
aggregates do
list :attendee_names, :attendees, :name
end
This error was thrown.
an exception was raised:
** (Spark.Error.DslError) [MyApp.MyDomainSoon.Event]
aggregates -> attendee_names:
relationship referenced in aggregate `MyApp.MyDomainSoon.Event.attendees` does not exist
(ash 2.19.14) lib/ash/resource/verifiers/validate_aggregates_supported.ex:29:
I would assume that one cannot list embedded “relationships”? I know that embedded resources themselves cannot have relationships or aggregates, but at least calculations (I did read the docs yes hopefully well enough though).
Most grateful for any input
Having such an amazing time with Ash!
So, there are two answers here, depending on what you need to be able to do with the value. One is easy and done with regular elixir, the other one is a bit more complicated but is also more flexible.
With a module calculation
defmodule AttendeeNames do
use Ash.Calculation
# ensure attendees is selected
def load(_, _, _), do: [:attendees]
def calculate(records, _, _) do
Enum.map(records, fn record ->
Enum.map(record.attendees, &(&1.name))
end)
end
end
calculate :attendee_names, {:array, :string}, AttendeeNames
This version can be used to display a value, but it cannot be used in filters/sorts, because it cannot be lowered to the data layer.
With an expression
calculate :attendee_names, {:array, :string}, expr(fragment("ARRAY_AGG(jsonb_array_elements(?)->>'name')", attendees))
You’ll need to play with the above expression to make sure it does what you want, thats just from memory.
With this one, you’ll be able to sort and filter on this calculated value.
1 Like
Many thanks Zach!
The module calculation is actually more than enough for now. But I will be needing to solve the json aggregation fairly soon. It does indeed need a little polishing.
I’ll make sure to post my results for posterity and mark the thread as solved
Thank you Zach!
1 Like