I’m trying to create a form which has a list of nested items, each of which contain some union field. I have the following hierarchy: WorkoutTemplate has many SetGroupTemplate where SetGroupTemplate looks like the following module and both FixedReps and ClassicOverload are embedded ash resources
defmodule Weightroom.Template.SetGroupTemplate do
@moduledoc false
use Ash.Resource,
domain: Weightroom.Template,
data_layer: AshPostgres.DataLayer
alias Weightroom.Template.Progression
attributes do
uuid_primary_key :id
attribute :order, :integer, public?: true, allow_nil?: false
attribute :progression, :union do
public? true
allow_nil? false
constraints types: [
fixed_reps: [
type: Progression.FixedReps,
tag: :type,
tag_value: :fixed_reps
],
classic_overload: [
type: Progression.ClassicOverload,
tag: :type,
tag_value: :classic_overload
]
]
end
end
relationships do
belongs_to :workout, Weightroom.Template.WorkoutTemplate do
allow_nil? false
end
belongs_to :exercise, Weightroom.Journal.Exercise do
allow_nil? false
public? true
end
end
postgres do
table "set_group_templates"
repo Weightroom.Repo
references do
reference :workout, on_delete: :delete
reference :exercise, on_delete: :delete
end
custom_statements do
statement :unique_order do
up ~s|ALTER TABLE set_group_templates ADD CONSTRAINT set_group_templates_unique_order_index UNIQUE (workout_id, "order") DEFERRABLE INITIALLY DEFERRED|
down "ALTER TABLE set_group_templates DROP CONSTRAINT set_group_templates_unique_order_index"
end
end
end
actions do
defaults [:read, :destroy, create: :*]
end
When I create the form and try to add a new SetGroupTemplate I get the following error
template
|> AshPhoenix.Form.for_update(:update, forms: [auto?: true])
|> AshPhoenix.Form.add_form("form[set_groups]",
params: %{
"progression" => %{
"_union_type" => "fixed_reps"
}
}
)
** (RuntimeError) Got no "_union_type" parameter, and no union type had a tag & tag_value pair matching the params.
If you are adding a form, select a type using `params: %{"_union_type" => "type_name"}`, or if one
or more of your types is using a tag you can set that tag with `params: %{"tag" => "tag_value"}`.
Params:
%{}
Available types:
[
classic_overload: [
type: Weightroom.Template.Progression.ClassicOverload,
constraints: [on_update: :update_on_match],
tag: :type,
tag_value: :classic_overload
],
fixed_reps: [
type: Weightroom.Template.Progression.FixedReps,
constraints: [on_update: :update_on_match],
tag: :type,
tag_value: :fixed_reps
]
]
If I instead use “type” instead of “_union_type” as the key for the new progression I get the same error. Stepping through the code of ash authentication it looks like AshPhoenix.Form.Auto.determine_type/3 is called twice. The first time with the map of params and it doesn’t raise. The second time, params is empty and the function raises.
I saw there is a test for union forms here and I can’t see what I’m doing differently other than using an embedded resource for the union type instead of a simple type like string/int/etc. Any help understanding where I’m going wrong would be appreciated.