mirror of
https://github.com/ash-project/ash_phoenix.git
synced 2024-09-19 06:42:47 +12:00
fix: properly fill union values on update
This commit is contained in:
parent
e333471888
commit
15afafee09
3 changed files with 143 additions and 80 deletions
|
@ -152,6 +152,9 @@ defmodule AshPhoenix.Form.Auto do
|
|||
|
||||
updater =
|
||||
fn opts, data, params ->
|
||||
if is_nil(data) and is_nil(params) do
|
||||
opts
|
||||
else
|
||||
{type_name, type, constraints, tag, tag_value} =
|
||||
determine_type(constraints, data, params)
|
||||
|
||||
|
@ -215,6 +218,7 @@ defmodule AshPhoenix.Form.Auto do
|
|||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
{attr.name,
|
||||
[
|
||||
|
@ -269,6 +273,14 @@ defmodule AshPhoenix.Form.Auto do
|
|||
determine_type(constraints, nil, params)
|
||||
end
|
||||
|
||||
defp determine_type(
|
||||
constraints,
|
||||
%AshPhoenix.Form.WrappedValue{value: %Ash.Union{} = union},
|
||||
params
|
||||
) do
|
||||
determine_type(constraints, union, params)
|
||||
end
|
||||
|
||||
defp determine_type(constraints, nil, params) when params == %{} do
|
||||
{key, config} = Enum.at(constraints[:types], 0)
|
||||
{key, config[:type], config[:constraints], config[:tag], config[:tag_value]}
|
||||
|
|
|
@ -370,11 +370,24 @@ defmodule AshPhoenix.Form do
|
|||
@doc "Calls the corresponding `for_*` function depending on the action type"
|
||||
def for_action(resource_or_data, action, opts \\ [])
|
||||
|
||||
def for_action(%Ash.Union{value: value, type: type}, action, opts) do
|
||||
def for_action(%Ash.Union{value: value, type: type} = union, action, opts) do
|
||||
opts =
|
||||
Keyword.put_new(opts, :transform_params, AshPhoenix.Form.Auto.union_param_transformer(type))
|
||||
|
||||
form = for_action(value, action, opts)
|
||||
data =
|
||||
case value do
|
||||
%struct{} = value ->
|
||||
if Ash.Resource.Info.resource?(struct) do
|
||||
value
|
||||
else
|
||||
%AshPhoenix.Form.WrappedValue{value: union}
|
||||
end
|
||||
|
||||
_value ->
|
||||
%AshPhoenix.Form.WrappedValue{value: union}
|
||||
end
|
||||
|
||||
form = for_action(data, action, opts)
|
||||
|
||||
%{form | params: Map.put(form.params, "_union_type", to_string(type))}
|
||||
end
|
||||
|
@ -4431,30 +4444,67 @@ defmodule AshPhoenix.Form do
|
|||
end
|
||||
|
||||
true ->
|
||||
if data && data != [] do
|
||||
if opts[:update_action] || opts[:read_action] do
|
||||
handle_form_without_params(
|
||||
forms,
|
||||
params,
|
||||
opts,
|
||||
key,
|
||||
domain,
|
||||
actor,
|
||||
tenant,
|
||||
trail,
|
||||
prev_data_trail,
|
||||
error?,
|
||||
name,
|
||||
id,
|
||||
transform_errors,
|
||||
warn_on_unhandled_errors?
|
||||
cond do
|
||||
!data ->
|
||||
{forms, params}
|
||||
|
||||
opts[:type] == :list ->
|
||||
form_values =
|
||||
data
|
||||
|> List.wrap()
|
||||
|> Enum.with_index()
|
||||
|> Enum.map(fn {data, index} ->
|
||||
opts = update_opts(opts, data, nil)
|
||||
|
||||
if opts[:update_action] do
|
||||
for_action(data, opts[:update_action],
|
||||
domain: domain,
|
||||
actor: actor,
|
||||
tenant: tenant,
|
||||
errors: error?,
|
||||
params: add_index(params, index, opts),
|
||||
accessing_from: opts[:managed_relationship],
|
||||
prepare_source: opts[:prepare_source],
|
||||
updater: opts[:updater],
|
||||
warn_on_unhandled_errors?: warn_on_unhandled_errors?,
|
||||
prev_data_trail: prev_data_trail,
|
||||
forms: opts[:forms] || [],
|
||||
transform_params: opts[:transform_params],
|
||||
transform_errors: transform_errors,
|
||||
as: name <> "[#{key}][#{index}]",
|
||||
id: id <> "_#{key}_#{index}"
|
||||
)
|
||||
else
|
||||
{forms, params}
|
||||
end
|
||||
else
|
||||
{forms, params}
|
||||
end)
|
||||
|
||||
{Map.put(forms, key, Enum.filter(form_values, & &1)), params}
|
||||
|
||||
true ->
|
||||
opts = update_opts(opts, data, nil)
|
||||
|
||||
form_value =
|
||||
if opts[:update_action] do
|
||||
for_action(data, opts[:update_action],
|
||||
domain: domain,
|
||||
actor: actor,
|
||||
tenant: tenant,
|
||||
errors: error?,
|
||||
accessing_from: opts[:managed_relationship],
|
||||
prepare_source: opts[:prepare_source],
|
||||
warn_on_unhandled_errors?: warn_on_unhandled_errors?,
|
||||
transform_params: opts[:transform_params],
|
||||
updater: opts[:updater],
|
||||
prev_data_trail: prev_data_trail,
|
||||
forms: opts[:forms] || [],
|
||||
transform_errors: transform_errors,
|
||||
as: name <> "[#{key}]",
|
||||
id: id <> "_#{key}"
|
||||
)
|
||||
end
|
||||
|
||||
{Map.put(forms, key, form_value), params}
|
||||
end
|
||||
|
||||
end
|
||||
else
|
||||
{forms, params}
|
||||
|
|
|
@ -346,11 +346,12 @@ defmodule AshPhoenix.AutoFormTest do
|
|||
"text" => "foobar"
|
||||
}
|
||||
)
|
||||
|> Phoenix.HTML.FormData.to_form([])
|
||||
|
||||
# |> Phoenix.HTML.FormData.to_form([])
|
||||
|
||||
# IO.inspect(Phoenix.Component.inputs_for(%{field: form[:union], __changed__: %{}}))
|
||||
# assert "update" == AshPhoenix.Form.value(form[:union], :value)
|
||||
assert Enum.at(form[:union].value, 0)[:value].value == %Ash.Union{
|
||||
value: :update,
|
||||
type: :predefined
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue