Attributes on `many_to_many` join/through resources.
Considering the following resources.
The following create attempt fails.
This is because attributes
defmodule Formula do
use Ash.Resource,
data_layer: Ash.DataLayer.Ets
attributes do
uuid_primary_key :id
create_timestamp :created_at
update_timestamp :updated_at
end
actions do
defaults([:create, :read, :update, :destroy])
create :define do
argument :formula, {:array, :map}
change manage_relationship(:formula, :reactants,
on_lookup: :relate,
on_no_match: :create,
on_match: :update,
on_missing: :unrelate
)
end
end
relationships do
many_to_many :reactants, Reactant do
through FormulaReactant
source_attribute_on_join_resource :formula_id
destination_attribute_on_join_resource :reactant_id
end
end
end
defmodule FormulaReactant do
use Ash.Resource,
data_layer: Ash.DataLayer.Ets
attributes do
attribute :quantity, :decimal do
allow_nil? false
constraints [min: 0.0]
end
attribute :unit, :string do
allow_nil? false
constraints trim?: true, allow_empty?: false, min_length: 1
end
end
actions do
defaults [:create, :read, :update, :destroy]
end
relationships do
belongs_to :formula, Formula, primary_key?: true, allow_nil?: false
belongs_to :reactant, Reactant, primary_key?: true, allow_nil?: false
end
end
defmodule Reactant do
use Ash.Resource,
data_layer: Ash.DataLayer.Ets
attributes do
uuid_primary_key :id
attribute :name, :string
create_timestamp :created_at
update_timestamp :updated_at
end
actions do
defaults([:create, :read, :update, :destroy])
end
enddefmodule Formula do
use Ash.Resource,
data_layer: Ash.DataLayer.Ets
attributes do
uuid_primary_key :id
create_timestamp :created_at
update_timestamp :updated_at
end
actions do
defaults([:create, :read, :update, :destroy])
create :define do
argument :formula, {:array, :map}
change manage_relationship(:formula, :reactants,
on_lookup: :relate,
on_no_match: :create,
on_match: :update,
on_missing: :unrelate
)
end
end
relationships do
many_to_many :reactants, Reactant do
through FormulaReactant
source_attribute_on_join_resource :formula_id
destination_attribute_on_join_resource :reactant_id
end
end
end
defmodule FormulaReactant do
use Ash.Resource,
data_layer: Ash.DataLayer.Ets
attributes do
attribute :quantity, :decimal do
allow_nil? false
constraints [min: 0.0]
end
attribute :unit, :string do
allow_nil? false
constraints trim?: true, allow_empty?: false, min_length: 1
end
end
actions do
defaults [:create, :read, :update, :destroy]
end
relationships do
belongs_to :formula, Formula, primary_key?: true, allow_nil?: false
belongs_to :reactant, Reactant, primary_key?: true, allow_nil?: false
end
end
defmodule Reactant do
use Ash.Resource,
data_layer: Ash.DataLayer.Ets
attributes do
uuid_primary_key :id
attribute :name, :string
create_timestamp :created_at
update_timestamp :updated_at
end
actions do
defaults([:create, :read, :update, :destroy])
end
endThe following create attempt fails.
Formula
|>Ash.Changeset.for_create(:define, %{formula: [%{name: "pinata"}]})
|>Api.create()Formula
|>Ash.Changeset.for_create(:define, %{formula: [%{name: "pinata"}]})
|>Api.create()This is because attributes
:quantity:quantity and :unit:unit are not being set on FormulaReactantFormulaReactant. How would a create action on FormulaFormula be setup to set both attributes?