Nested aggregates
In my Product Data Management webapp I'm trying to build with Ash, I have the following resources with attributes and relatioships in
App.Api
that, combined, construct/define an Item
.
* Category
: has a :code
attribute
* Family
: belongs_to
a Category (and also has a :name
, etc.)
* Variant
: belongs_to
a Variant, has a :code
attribute
The idea is that an Item
belongs_to
a Category and a Variant, and has a calculated attribute (also called :code) resulting from concatenating the Category :code
and the Variant :code
.
This means that Item
's :code
calculation must "pull" Category's :code
through the Variant it belongs to, which belongs to a Family, which belongs to a Category.
Item
's calculated :code
uniquely identifies a record.
I have tried the following in a cascade,
In lib/app/resources/item.ex
:
In lib/app/resources/variant.ex
:
In lib/app/resources/family.ex
:
...hoping that App.Api.Item |> App.Api.read!
would return records on which I can App.Api.load!(:code)
.
Instead:
What is the Ash-idiomatic way of achieving the goal of being able to access Item
's :code
?24 Replies
You can’t currently reference aggregates from other aggregates
However aggregates accept a relationship path.
So you can say
first [:foo, :bar, :baz], :code
I need to give that a better error for sure.first [:variant, :family, :category], :code
?
it's getting marked as an error in VSCode (first/2
is not definedAh, sorry
My example was bad
The first argument is the name
So it’s name, path, field
Awesome!
I also just realized that
eval
automatically casts the arguments to strings?
Both aggregates refer to :integer
types in the other resources, but the result of the :code
calculation is a :string
Yeah, because the
:<>
operator is typed
🙂nice!
Thank you, wow are there lots of things I'm learning, thank you for all the help!
Glad to be of assistance!
Though, now this works:
but this doesn't:
I'm getting
** (Postgrex.Error) ERROR 42883 (undefined_function) operator does not exist: bigint || bigint
.🥲
I think you may need the type casts then
(I learned about preparations from another #support post)
That is likely a bug in ash_postgres
as a workaround? how?
Wrapping the things you’re concatenating with
type(thing, :string)
wait, in the calculations or in the preparations block?
In the calculation
Like the typed operator thing I mentioned must not be doing the right thing for ash_postgres
same error
The codes have to be cast to strings also
let me check, can I :load it or is it a preparations issue?
Ash doesn’t always go to the database to load things
in the aggregates first definitions?
So loading it after the fact might work
In the example you showed change integer to string
yep, it works now!
also, loading
:code
after the fact works when I didn't add it to the prepare
statement
this is one of the most important things I learnedYeah because Ash will sometimes choose to figure out calculations without going to the database.
And so the elixir evaluation of that must work
But the postgres one doesn’t
Can you log a bug in ash_postgres?
Sure thing, here you go! https://github.com/ash-project/ash_postgres/issues/130
GitHub
Preparation does not work on a calculation, except when its paramet...
Describe the bug Preparation does not work on a calculation, except when its parameters are cast as strings. To Reproduce The following is a part of resource App.Api.Item. A Variant has_one Item, a...