fix: simplify and fix duplicate detection in embedded resources

This commit is contained in:
Zach Daniel 2023-08-22 19:02:38 -04:00
parent b3f9a359d7
commit 221280f1f5

View file

@ -441,56 +441,37 @@ defmodule Ash.EmbeddableType do
end end
end end
defp find_duplicates(term, unique_keys) do defp find_duplicates([], _), do: nil
defp find_duplicates([_item], _), do: nil
defp find_duplicates(list, unique_keys) do
Enum.find(unique_keys, fn unique_key -> Enum.find(unique_keys, fn unique_key ->
has_duplicates?(term, __MODULE__, fn item -> attributes = Enum.map(unique_key, &Ash.Resource.Info.attribute(__MODULE__, &1))
Enum.reduce(unique_key, %{}, fn key, acc ->
if Map.has_key?(item, key) || Map.has_key?(item, to_string(key)) do
attribute = Ash.Resource.Info.attribute(__MODULE__, key)
case Ash.Type.cast_input( Enum.reduce_while(list, list, fn
attribute.type, _term, [_] ->
Map.get(item, key) || Map.get(item, to_string(key)), {:halt, false}
attribute.constraints
) do
{:ok, value} ->
Map.put(acc, key, value)
_ -> this, [_| rest] ->
acc has_duplicate? =
end Enum.any?(rest, fn other ->
Enum.all?(attributes, fn attribute ->
this_value = Map.get(this, attribute.name)
other_value = Map.get(other, attribute.name)
not is_nil(this_value) and not is_nil(other_value) and
Ash.Type.equal?(attribute.type, this_value, other_value)
end)
end)
if has_duplicate? do
{:halt, true}
else
{:cont, rest}
end end
end)
end) end)
end) end)
end end
defp has_duplicates?(list, resource, func) do
list
|> Enum.reduce_while(MapSet.new(), fn x, acc ->
x = func.(x)
acc
|> Enum.any?(fn item ->
Enum.all?(x, fn {key, value} ->
attr = Ash.Resource.Info.attribute(resource, key)
Enum.any?(acc, fn other ->
Ash.Type.equal?(attr.type, Map.get(other, key), value)
end)
end)
end)
|> case do
true ->
{:halt, 0}
false ->
{:cont, MapSet.put(acc, x)}
end
end)
|> is_integer()
end
def handle_change_array(nil, new_values, constraints) do def handle_change_array(nil, new_values, constraints) do
handle_change_array([], new_values, constraints) handle_change_array([], new_values, constraints)
end end