diff --git a/lib/ash/changeset/changeset.ex b/lib/ash/changeset/changeset.ex index 5bf7bd52..755147e3 100644 --- a/lib/ash/changeset/changeset.ex +++ b/lib/ash/changeset/changeset.ex @@ -503,13 +503,14 @@ defmodule Ash.Changeset do Ash.Tracer.set_metadata(opts[:tracer], :changeset, metadata) changeset + |> Map.put(:action, action) + |> reset_arguments() |> handle_errors(action.error_handler) |> set_actor(opts) |> set_authorize(opts) |> set_tracer(opts) |> set_tenant(opts[:tenant] || changeset.tenant) |> Map.put(:__validated_for_action__, action.name) - |> Map.put(:action, action) |> cast_params(action, params) |> set_argument_defaults(action) |> require_arguments(action) @@ -533,6 +534,14 @@ defmodule Ash.Changeset do end end + defp reset_arguments(%{arguments: arguments} = changeset) when is_map(arguments) do + Enum.reduce(arguments, changeset, fn {key, value}, changeset -> + set_argument(changeset, key, value) + end) + end + + defp reset_arguments(changeset), do: changeset + @spec set_on_upsert(t(), list(atom)) :: Keyword.t() def set_on_upsert(changeset, upsert_keys) do keys = upsert_keys || Ash.Resource.Info.primary_key(changeset.resource) @@ -627,6 +636,8 @@ defmodule Ash.Changeset do changeset = changeset + |> Map.put(:action, action) + |> reset_arguments() |> handle_errors(action.error_handler) |> set_actor(opts) |> set_authorize(opts) @@ -635,7 +646,6 @@ defmodule Ash.Changeset do |> set_tenant( opts[:tenant] || changeset.tenant || changeset.data.__metadata__[:tenant] ) - |> Map.put(:action, action) |> Map.put(:__validated_for_action__, action.name) |> cast_params(action, params || %{}) |> set_argument_defaults(action) diff --git a/lib/ash/query/query.ex b/lib/ash/query/query.ex index 8fc72a2d..5d6e8d39 100644 --- a/lib/ash/query/query.ex +++ b/lib/ash/query/query.ex @@ -294,15 +294,14 @@ defmodule Ash.Query do Ash.Tracer.set_metadata(opts[:tracer], :query, metadata) - query = Map.put(query, :action, action.name) - query + |> Map.put(:action, action) + |> reset_arguments() |> timeout(query.timeout || opts[:timeout]) |> set_actor(opts) |> set_authorize?(opts) |> set_tracer(opts) |> Ash.Query.set_tenant(opts[:tenant] || query.tenant) - |> Map.put(:action, action) |> Map.put(:__validated_for_action__, action_name) |> cast_params(action, args) |> set_argument_defaults(action) @@ -1109,6 +1108,14 @@ defmodule Ash.Query do end end + defp reset_arguments(%{arguments: arguments} = query) when is_map(arguments) do + Enum.reduce(arguments, query, fn {key, value}, query -> + set_argument(query, key, value) + end) + end + + defp reset_arguments(query), do: query + defp add_invalid_errors(query, argument, error) do messages = if Keyword.keyword?(error) do diff --git a/lib/ash/type/type.ex b/lib/ash/type/type.ex index a72971ea..fbf97c0b 100644 --- a/lib/ash/type/type.ex +++ b/lib/ash/type/type.ex @@ -516,7 +516,7 @@ defmodule Ash.Type do case list_constraint_errors do [] -> - nil_items? = Keyword.get(constraints, :nil_items?, true) + nil_items? = Keyword.get(constraints, :nil_items?, false) item_constraints = constraints[:items] || [] if item_constraints != [] || !nil_items? do @@ -593,14 +593,14 @@ defmodule Ash.Type do |> Enum.reduce([], fn {:min_length, min_length}, errors -> if length < min_length do - [message: "must have %{min} or more items", min: min_length] + [message: "must have %{min} or more items", vars: [min: min_length]] else errors end {:max_length, max_length}, errors -> if length > max_length do - [message: "must have %{max} or fewer items", max: max_length] + [message: "must have %{max} or fewer items", vars: [max: max_length]] else errors end