Ash FrameworkAF
Ash Framework3y ago
42 replies
waseigo

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:
  aggregates do
    first :category_code, :variant, :category_code
  end


In lib/app/resources/variant.ex:
  aggregates do
    first :category_code, :family, :category_code
  end


In lib/app/resources/family.ex:
  aggregates do
    first :category_code, :category, :code
  end


...hoping that App.Api.Item |> App.Api.read! would return records on which I can App.Api.load!(:code).

Instead:
** (CaseClauseError) no case clause matching: {:error, [%Ash.Error.Unknown.UnknownError{error: "Must provide field type for first", field: nil, changeset: nil, query: nil, error_context: ["Loading aggregate: :category_code for query: #Ash.Query<resource: App.Api.Variant>"], vars: [], path: [:aggregates], stacktrace: #Stacktrace<>, class: :unknown}]}


What is the Ash-idiomatic way of achieving the goal of being able to access Item's :code?
Was this page helpful?