fix: don't validate values that aren't maps

This commit is contained in:
Zach Daniel 2022-08-23 22:26:04 -04:00
parent 2e061428a4
commit 7b9f3070a6

View file

@ -937,147 +937,155 @@ defmodule AshPhoenix.Form do
form_params || %{} form_params || %{}
end end
new_forms = if values_are_maps(form_params) do
Enum.reduce(form_params, forms, fn {index, params}, forms -> new_forms =
case Enum.find(form.forms[key] || [], &matcher.(&1, params, form, key, index)) do Enum.reduce(form_params, forms, fn {index, params}, forms ->
nil -> case Enum.find(form.forms[key] || [], &matcher.(&1, params, form, key, index)) do
new_form = nil ->
cond do new_form =
!opts[:create_action] && !opts[:read_action] -> cond do
raise AshPhoenix.Form.NoActionConfigured, !opts[:create_action] && !opts[:read_action] ->
path: form.name <> "[#{key}][#{index}]", raise AshPhoenix.Form.NoActionConfigured,
action: :create_or_read path: form.name <> "[#{key}][#{index}]",
action: :create_or_read
opts[:create_action] -> opts[:create_action] ->
create_action = opts[:create_action] create_action = opts[:create_action]
resource = resource =
opts[:create_resource] || opts[:resource] || opts[:create_resource] || opts[:resource] ||
raise AshPhoenix.Form.NoResourceConfigured, raise AshPhoenix.Form.NoResourceConfigured,
path: Enum.reverse(trail, [key]) path: Enum.reverse(trail, [key])
for_action(resource, create_action, for_action(resource, create_action,
params: params, params: params,
forms: opts[:forms] || [], forms: opts[:forms] || [],
transform_params: opts[:transform_params], transform_params: opts[:transform_params],
errors: errors?, errors: errors?,
warn_on_unhandled_errors?: form.warn_on_unhandled_errors?, warn_on_unhandled_errors?: form.warn_on_unhandled_errors?,
prev_data_trail: prev_data_trail, prev_data_trail: prev_data_trail,
transform_errors: form.transform_errors, transform_errors: form.transform_errors,
as: form.name <> "[#{key}][#{index}]", as: form.name <> "[#{key}][#{index}]",
id: form.id <> "_#{key}_#{index}" id: form.id <> "_#{key}_#{index}"
) )
opts[:read_action] -> opts[:read_action] ->
create_action = opts[:read_action] create_action = opts[:read_action]
resource = resource =
opts[:read_resource] || opts[:resource] || opts[:read_resource] || opts[:resource] ||
raise AshPhoenix.Form.NoResourceConfigured, raise AshPhoenix.Form.NoResourceConfigured,
path: Enum.reverse(trail, [key]) path: Enum.reverse(trail, [key])
for_action(resource, create_action, for_action(resource, create_action,
params: params, params: params,
transform_params: opts[:transform_params], transform_params: opts[:transform_params],
forms: opts[:forms] || [], forms: opts[:forms] || [],
errors: errors?, errors: errors?,
warn_on_unhandled_errors?: form.warn_on_unhandled_errors?, warn_on_unhandled_errors?: form.warn_on_unhandled_errors?,
prev_data_trail: prev_data_trail, prev_data_trail: prev_data_trail,
transform_errors: form.transform_errors, transform_errors: form.transform_errors,
as: form.name <> "[#{key}][#{index}]", as: form.name <> "[#{key}][#{index}]",
id: form.id <> "_#{key}_#{index}" id: form.id <> "_#{key}_#{index}"
) )
end end
Map.update(forms, key, [new_form], &(&1 ++ [new_form])) Map.update(forms, key, [new_form], &(&1 ++ [new_form]))
matching_form -> matching_form ->
validated = validated =
validate(matching_form, params, validate(matching_form, params,
errors: errors?, errors: errors?,
matcher: matcher, matcher: matcher,
prev_data_trail?: prev_data_trail prev_data_trail?: prev_data_trail
) )
|> Map.put(:as, form.name <> "[#{key}][#{index}]") |> Map.put(:as, form.name <> "[#{key}][#{index}]")
|> Map.put(:id, form.id <> "_#{key}_#{index}") |> Map.put(:id, form.id <> "_#{key}_#{index}")
Map.update(forms, key, [validated], fn nested_forms -> Map.update(forms, key, [validated], fn nested_forms ->
nested_forms ++ nested_forms ++
[validated] [validated]
end) end)
end end
end)
new_forms =
if Map.has_key?(new_forms, opts[:as] || key) do
Map.update!(new_forms, opts[:as] || key, fn nested_forms ->
Enum.sort_by(nested_forms, & &1.id)
end) end)
else
new_forms
end
new_params = new_forms =
if Map.has_key?(new_forms, opts[:as] || key) do if Map.has_key?(new_forms, opts[:as] || key) do
new_nested = Map.update!(new_forms, opts[:as] || key, fn nested_forms ->
new_forms Enum.sort_by(nested_forms, & &1.id)
|> Map.get(opts[:as] || key)
|> List.wrap()
|> Enum.with_index()
|> Map.new(fn {form, index} ->
{to_string(index),
apply_or_return(form.params, form.transform_params, :nested)}
end) end)
else
new_forms
end
Map.put(params, to_string(opts[:as] || key), new_nested) new_params =
else if Map.has_key?(new_forms, opts[:as] || key) do
params new_nested =
end new_forms
|> Map.get(opts[:as] || key)
|> List.wrap()
|> Enum.with_index()
|> Map.new(fn {form, index} ->
{to_string(index),
apply_or_return(form.params, form.transform_params, :nested)}
end)
{new_forms, new_params} Map.put(params, to_string(opts[:as] || key), new_nested)
else
params
end
{new_forms, new_params}
else
{forms, params}
end
else else
new_forms = if is_map(form_params) do
if form.forms[key] do new_forms =
new_form = if form.forms[key] do
validate(form.forms[key], form_params, errors: errors?, matcher: matcher) new_form =
validate(form.forms[key], form_params, errors: errors?, matcher: matcher)
Map.put(forms, key, new_form) Map.put(forms, key, new_form)
else else
create_action = create_action =
opts[:create_action] || opts[:create_action] ||
raise AshPhoenix.Form.NoActionConfigured, raise AshPhoenix.Form.NoActionConfigured,
path: form.name <> "[#{key}]", path: form.name <> "[#{key}]",
action: :create action: :create
resource = resource =
opts[:create_resource] || opts[:resource] || opts[:create_resource] || opts[:resource] ||
raise AshPhoenix.Form.NoResourceConfigured, raise AshPhoenix.Form.NoResourceConfigured,
path: form.name <> "[#{key}]" path: form.name <> "[#{key}]"
new_form = new_form =
for_action(resource, create_action, for_action(resource, create_action,
params: form_params, params: form_params,
transform_params: opts[:transform_params], transform_params: opts[:transform_params],
warn_on_unhandled_errors?: form.warn_on_unhandled_errors?, warn_on_unhandled_errors?: form.warn_on_unhandled_errors?,
forms: opts[:forms] || [], forms: opts[:forms] || [],
errors: errors?, errors: errors?,
prev_data_trail: prev_data_trail, prev_data_trail: prev_data_trail,
transform_errors: form.transform_errors, transform_errors: form.transform_errors,
as: form.name <> "[#{key}]", as: form.name <> "[#{key}]",
id: form.id <> "_#{key}" id: form.id <> "_#{key}"
) )
Map.put(forms, key, new_form) Map.put(forms, key, new_form)
end end
new_params = new_params =
Map.put( Map.put(
params, params,
to_string(opts[:as] || key), to_string(opts[:as] || key),
apply_or_return(new_forms[key].params, new_forms[key].transform_params, :nested) apply_or_return(new_forms[key].params, new_forms[key].transform_params, :nested)
) )
{new_forms, new_params} {new_forms, new_params}
else
{forms, params}
end
end end
_ -> _ ->
@ -1222,6 +1230,14 @@ defmodule AshPhoenix.Form do
end) end)
end end
defp values_are_maps(map) when is_map(map) do
map
|> Map.values()
|> Enum.all?(&is_map/1)
end
defp values_are_maps(_), do: false
@submit_opts [ @submit_opts [
force?: [ force?: [
type: :boolean, type: :boolean,