fix: ignore?: true still accumulates changes

fix: properly require_attributes before setting defaults
This commit is contained in:
Zach Daniel 2021-05-18 01:44:10 -04:00
parent e43ca47ec4
commit 013b49c2b2
4 changed files with 29 additions and 31 deletions

View file

@ -47,6 +47,7 @@ defmodule Ash.Actions.ManagedRelationships do
end)
|> Enum.flat_map(fn {relationship, inputs} ->
inputs
|> Enum.reject(fn {_, opts} -> opts[:ignore?] end)
|> Enum.with_index()
|> Enum.map(fn {{input, opts}, index} ->
{{relationship, {input, opts}}, index}
@ -321,6 +322,7 @@ defmodule Ash.Actions.ManagedRelationships do
end)
|> Enum.flat_map(fn {key, batches} ->
batches
|> Enum.reject(fn {_, opts} -> opts[:ignore?] end)
|> Enum.with_index()
|> Enum.map(fn {{batch, opts}, index} ->
opts = Keyword.put(opts, :authorize?, engine_opts[:authorize?] && opts[:authorize?])

View file

@ -455,9 +455,9 @@ defmodule Ash.Changeset do
|> Map.put(:__validated_for_action__, action.name)
|> cast_params(action, params || %{}, opts)
|> validate_attributes_accepted(action)
|> set_defaults(changeset.action_type, false)
|> run_action_changes(action, opts[:actor])
|> require_values(action.type, false, action.require_attributes)
|> run_action_changes(action, opts[:actor])
|> set_defaults(changeset.action_type, false)
|> add_validations()
|> mark_validated(action.name)
|> require_arguments(action)
@ -1076,10 +1076,6 @@ defmodule Ash.Changeset do
end
@manage_opts [
ignore?: [
type: :any,
hide: true
],
type: [
type: {:one_of, @manage_types},
doc: """
@ -1227,6 +1223,14 @@ defmodule Ash.Changeset do
type: :any,
doc:
"Freeform data that will be retained along with the options, which can be used to track/manage the changes that are added to the `relationships` key."
],
ignore?: [
type: :any,
default: false,
doc: """
This tells Ash to ignore the provided inputs when actually running the action. This can be useful for
building up a set of instructions that you intend to handle manually
"""
]
]

View file

@ -34,10 +34,6 @@ defmodule Ash.Resource.Change.Builtins do
```elixir
change manage_relationship(:add_comments, :comments, on_missing: :ignore, on_match: :no_match, on_no_match: {:create, :add_comment_to_post}
```
A special `:ignore?` option can be passed to tell the change not to actually happen.
This is useful specifically if you have tooling that looks for `manage_relationship` changes,
like `ash_admin`, but you want to actually handle the input yourself.
"""
def manage_relationship(argument, relationship_name \\ nil, opts) do
relationship_name = relationship_name || argument

View file

@ -8,30 +8,26 @@ defmodule Ash.Resource.Change.ManageRelationship do
end
def change(changeset, opts, _) do
if opts[:ignore?] do
changeset
else
case Changeset.fetch_argument(changeset, opts[:argument]) do
{:ok, argument_value} ->
destination = Ash.Resource.Info.related(changeset.resource, opts[:relationship])
argument_value = from_structs(argument_value, destination)
case Changeset.fetch_argument(changeset, opts[:argument]) do
{:ok, argument_value} ->
destination = Ash.Resource.Info.related(changeset.resource, opts[:relationship])
argument_value = from_structs(argument_value, destination)
manage_opts =
opts[:opts]
|> Kernel.||([])
|> Keyword.put_new(:meta, [])
|> Keyword.update!(:meta, &Keyword.put(&1, :id, opts[:argument]))
manage_opts =
opts[:opts]
|> Kernel.||([])
|> Keyword.put_new(:meta, [])
|> Keyword.update!(:meta, &Keyword.put(&1, :id, opts[:argument]))
Ash.Changeset.manage_relationship(
changeset,
opts[:relationship],
argument_value,
manage_opts
)
Ash.Changeset.manage_relationship(
changeset,
opts[:relationship],
argument_value,
manage_opts
)
:error ->
changeset
end
:error ->
changeset
end
end