fix: handle error case in create

improvement: add `ref` template helper
fix: don't require attributes if an argument overrides them
This commit is contained in:
Zach Daniel 2022-03-20 20:39:47 -04:00
parent 7ba9715f27
commit 23ea0ee056
4 changed files with 24 additions and 13 deletions

View file

@ -49,9 +49,13 @@ defmodule Ash.Actions.Create do
{:ok, %{data: %{commit: %^resource{} = created}} = engine_result} -> {:ok, %{data: %{commit: %^resource{} = created}} = engine_result} ->
add_notifications(created, engine_result, return_notifications?) add_notifications(created, engine_result, return_notifications?)
{:error, %Ash.Engine.Runner{errors: errors, changeset: runner_changeset}} -> {:error, %Ash.Engine.Runner{errors: errors, changeset: %Ash.Changeset{} = runner_changeset}} ->
errors = Helpers.process_errors(changeset, errors) errors = Helpers.process_errors(changeset, errors)
{:error, Ash.Error.to_error_class(errors, changeset: runner_changeset || changeset)} {:error, Ash.Error.to_error_class(errors, changeset: runner_changeset)}
{:error, %Ash.Engine.Runner{errors: errors}} ->
errors = Helpers.process_errors(changeset, errors)
{:error, Ash.Error.to_error_class(errors, changeset: changeset)}
{:error, error} -> {:error, error} ->
error = Helpers.process_errors(changeset, error) error = Helpers.process_errors(changeset, error)

View file

@ -996,10 +996,13 @@ defmodule Ash.Changeset do
[] []
end end
masked_argument_names = Enum.map(action.arguments, & &1.name)
resource resource
|> Ash.Resource.Info.attributes() |> Ash.Resource.Info.attributes()
|> Enum.reject( |> Enum.reject(
&(&1.allow_nil? || &1.private? || !&1.writable? || &1.generated? || &1.name in belongs_to || &(&1.allow_nil? || &1.private? || !&1.writable? || &1.generated? ||
&1.name in masked_argument_names || &1.name in belongs_to ||
&1.name in allow_nil_input) &1.name in allow_nil_input)
) )
end end

View file

@ -7,6 +7,12 @@ defmodule Ash.Filter.TemplateHelpers do
@doc "A helper for using action arguments in filter templates" @doc "A helper for using action arguments in filter templates"
def arg(name), do: {:_arg, name} def arg(name), do: {:_arg, name}
@doc "A helper for creating a reference"
def ref(name), do: {:_ref, [], name}
@doc "A helper for creating a reference to a related path"
def ref(path, name), do: {:_ref, path, name}
@doc """ @doc """
A helper for using query context in filter templates A helper for using query context in filter templates

View file

@ -407,12 +407,6 @@ defmodule Ash.Query do
end end
end end
defmacro expr({var, _, context} = binding) when is_atom(var) and is_atom(context) do
quote do
unquote(binding)
end
end
defmacro expr(body) do defmacro expr(body) do
if Keyword.keyword?(body) do if Keyword.keyword?(body) do
quote do quote do
@ -431,6 +425,14 @@ defmodule Ash.Query do
defp do_expr(expr, escape? \\ true) defp do_expr(expr, escape? \\ true)
defp do_expr({op, _, nil}, escape?) when is_atom(op) do
soft_escape(%Ash.Query.Ref{relationship_path: [], attribute: op}, escape?)
end
defp do_expr({op, _, Elixir}, escape?) when is_atom(op) do
soft_escape(%Ash.Query.Ref{relationship_path: [], attribute: op}, escape?)
end
defp do_expr({:^, _, [value]}, _escape?) do defp do_expr({:^, _, [value]}, _escape?) do
value value
end end
@ -545,10 +547,6 @@ defmodule Ash.Query do
end end
end end
defp do_expr({op, _, nil}, escape?) when is_atom(op) do
soft_escape(%Ash.Query.Ref{relationship_path: [], attribute: op}, escape?)
end
defp do_expr({op, _, args}, escape?) when op in [:and, :or] do defp do_expr({op, _, args}, escape?) when op in [:and, :or] do
args = Enum.map(args, &do_expr(&1, false)) args = Enum.map(args, &do_expr(&1, false))