diff --git a/lib/ash_phoenix/form/auto.ex b/lib/ash_phoenix/form/auto.ex index c743097..62c3705 100644 --- a/lib/ash_phoenix/form/auto.ex +++ b/lib/ash_phoenix/form/auto.ex @@ -177,8 +177,12 @@ defmodule AshPhoenix.Form.Auto do transform_params = if fake_embedded? do - fn form, _params, _type -> - AshPhoenix.Form.value(form, :value) + fn form, params, type -> + if type == :nested do + AshPhoenix.Form.value(form, :value) + else + params + end end end @@ -244,11 +248,11 @@ defmodule AshPhoenix.Form.Auto do Params: - #{inspect(params)} + #{inspect(params, pretty: true)} Available types: - #{inspect(constraints[:types])} + #{inspect(constraints[:types], pretty: true)} """ {_key, config} -> @@ -266,13 +270,16 @@ defmodule AshPhoenix.Form.Auto do raise """ 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: - #{inspect(params)} + #{inspect(params, pretty: true)} Available types: - #{inspect(constraints[:types])} + #{inspect(constraints[:types], pretty: true)} """ {_key, config} -> @@ -823,6 +830,8 @@ defmodule AshPhoenix.Form.Auto do |> Keyword.new() end + defp union?({:array, type}), do: union?(type) + defp union?(type) do if Ash.Type.NewType.new_type?(type) do union?(Ash.Type.NewType.subtype_of(type)) diff --git a/lib/ash_phoenix/form/form.ex b/lib/ash_phoenix/form/form.ex index 96f0ed0..1ce260d 100644 --- a/lib/ash_phoenix/form/form.ex +++ b/lib/ash_phoenix/form/form.ex @@ -1182,7 +1182,7 @@ defmodule AshPhoenix.Form do Map.update(forms, key, [new_form], &(&1 ++ [new_form])) matching_form -> - opts = update_opts(opts, matching_form.data, form_params) + opts = update_opts(opts, matching_form.data, params) validated = validate(matching_form, params, @@ -2889,6 +2889,13 @@ defmodule AshPhoenix.Form do fields -> Keyword.put(hidden, :_touched, fields) end + hidden = + if form.params["_union_type"] do + Keyword.put(hidden, :_union_type, form.params["_union_type"]) + else + hidden + end + if form.params["_index"] && form.params["_index"] != "" do Keyword.put(hidden, :_index, form.params["_index"]) else diff --git a/test/auto_form_test.exs b/test/auto_form_test.exs index 384f015..80fb8fc 100644 --- a/test/auto_form_test.exs +++ b/test/auto_form_test.exs @@ -2,7 +2,8 @@ defmodule AshPhoenix.AutoFormTest do use ExUnit.Case alias AshPhoenix.Form.Auto - alias AshPhoenix.Test.Post + alias AshPhoenix.Test.{Api, Post} + import Phoenix.HTML.Form, only: [form_for: 2] import AshPhoenix.Form, only: [update_opts: 2] test "it works for simple relationships" do @@ -53,6 +54,80 @@ defmodule AshPhoenix.AutoFormTest do assert validated.source.arguments[:comment_ids] == [1] end + describe "single unions" do + test "a form can be added for a union" do + Post + |> AshPhoenix.Form.for_create(:create, + api: Api, + forms: [ + auto?: true + ] + ) + |> AshPhoenix.Form.add_form(:union, params: %{"type" => "foo"}) + |> form_for("action") + end + + test "a form can be removed from a union" do + form = + Post + |> AshPhoenix.Form.for_create(:create, + api: Api, + forms: [ + auto?: true + ] + ) + |> AshPhoenix.Form.add_form(:union, params: %{"type" => "foo"}) + |> form_for("action") + + AshPhoenix.Form.remove_form(form, [:union]) + end + + test "a form can be added for a non-embedded type" do + Post + |> AshPhoenix.Form.for_create(:create, + api: Api, + forms: [ + auto?: true + ], + params: %{ + "text" => "foobar" + } + ) + |> AshPhoenix.Form.add_form(:union, params: %{"_union_type" => "bar", "value" => 10}) + |> AshPhoenix.Form.submit!() + end + end + + describe "list unions" do + test "a form can be added for a union" do + Post + |> AshPhoenix.Form.for_create(:create, + api: Api, + forms: [ + auto?: true + ] + ) + |> AshPhoenix.Form.add_form(:union_array, params: %{"type" => "foo"}) + |> form_for("action") + end + + test "a form can be removed from a union" do + form = + Post + |> AshPhoenix.Form.for_create(:create, + api: Api, + forms: [ + auto?: true + ] + ) + |> AshPhoenix.Form.add_form(:union_array, params: %{"type" => "foo"}) + |> form_for("action") + + AshPhoenix.Form.remove_form(form, [:union_array, 0]) + end + end + + defp auto_forms(resource, action) do [forms: Auto.auto(resource, action)] end diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 120a1e9..675c264 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -10,6 +10,7 @@ defmodule AshPhoenix.Test.Post do uuid_primary_key(:id) attribute(:text, :string, allow_nil?: false) attribute(:union, AshPhoenix.Test.UnionValue) + attribute(:union_array, {:array, AshPhoenix.Test.UnionValue}) attribute(:title, :string) end