Skip to content

Commit

Permalink
fix: apply atomic validations on non-bulk destroy actions
Browse files Browse the repository at this point in the history
chore: don't put atomic changes into attributes to simplify
  • Loading branch information
zachdaniel committed Jul 22, 2024
1 parent 5be7a56 commit c65f0c8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 33 deletions.
2 changes: 2 additions & 0 deletions lib/ash/actions/destroy/destroy.ex
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ defmodule Ash.Actions.Destroy do
with %{valid?: true} = changeset <- Ash.Changeset.validate_multitenancy(changeset),
%{valid?: true} = changeset <- changeset(changeset, domain, action, opts),
%{valid?: true} = changeset <- authorize(changeset, opts),
%{valid?: true} = changeset <-
Ash.Changeset.add_atomic_validations(changeset, opts[:actor], []),
{:ok, result, instructions} <- commit(changeset, domain, opts) do
changeset.resource
|> add_notifications(
Expand Down
1 change: 0 additions & 1 deletion lib/ash/actions/update/bulk.ex
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,6 @@ defmodule Ash.Actions.Update.Bulk do
authorize_atomic_changeset(query, atomic_changeset, opts),
{query, atomic_changeset} <-
add_changeset_filters(query, atomic_changeset),
atomic_changeset <- Ash.Changeset.move_attributes_to_atomics(atomic_changeset),
%Ash.Changeset{valid?: true} = atomic_changeset <-
Ash.Changeset.handle_allow_nil_atomics(atomic_changeset, opts[:actor]),
atomic_changeset <- sort_atomic_changes(atomic_changeset),
Expand Down
49 changes: 17 additions & 32 deletions lib/ash/changeset/changeset.ex
Original file line number Diff line number Diff line change
Expand Up @@ -947,21 +947,16 @@ defmodule Ash.Changeset do
{:cont, %{changeset | arguments: Map.put(changeset.arguments, key, value)}}

attribute = Ash.Resource.Info.attribute(changeset.resource, key) ->
if Ash.Expr.expr?(value) do
case Ash.Type.cast_atomic(attribute.type, value, attribute.constraints) do
{:atomic, atomic} ->
atomic = set_error_field(atomic, attribute.name)
{:cont, atomic_update(changeset, attribute.name, {:atomic, atomic})}
case Ash.Type.cast_atomic(attribute.type, value, attribute.constraints) do
{:atomic, atomic} ->
atomic = set_error_field(atomic, attribute.name)
{:cont, atomic_update(changeset, attribute.name, {:atomic, atomic})}

{:error, error} ->
{:cont, add_invalid_errors(value, :attribute, changeset, attribute, error)}
{:error, error} ->
{:cont, add_invalid_errors(value, :attribute, changeset, attribute, error)}

{:not_atomic, reason} ->
{:halt, {:not_atomic, reason}}
end
else
{:cont,
%{changeset | attributes: Map.put(changeset.attributes, attribute.name, value)}}
{:not_atomic, reason} ->
{:halt, {:not_atomic, reason}}
end

match?("_" <> _, key) ->
Expand Down Expand Up @@ -992,19 +987,15 @@ defmodule Ash.Changeset do
attribute = Ash.Resource.Info.attribute(changeset.resource, key) ->
cond do
attribute.name in action.accept ->
if Ash.Expr.expr?(value) do
case Ash.Type.cast_atomic(attribute.type, value, attribute.constraints) do
{:atomic, atomic} ->
{:cont, atomic_update(changeset, attribute.name, {:atomic, atomic})}
case Ash.Type.cast_atomic(attribute.type, value, attribute.constraints) do
{:atomic, atomic} ->
{:cont, atomic_update(changeset, attribute.name, {:atomic, atomic})}

{:error, error} ->
{:cont, add_invalid_errors(value, :attribute, changeset, attribute, error)}
{:error, error} ->
{:cont, add_invalid_errors(value, :attribute, changeset, attribute, error)}

{:not_atomic, reason} ->
{:halt, {:not_atomic, reason}}
end
else
{:cont, force_change_attribute(changeset, attribute.name, value)}
{:not_atomic, reason} ->
{:halt, {:not_atomic, reason}}
end

key in List.wrap(opts[:skip_unknown_inputs]) ->
Expand Down Expand Up @@ -1477,13 +1468,6 @@ defmodule Ash.Changeset do
end
end

@doc false
def move_attributes_to_atomics(changeset) do
Enum.reduce(changeset.attributes, changeset, fn {key, value}, changeset ->
%{changeset | atomics: Keyword.put_new(changeset.atomics, key, value)}
end)
end

@doc false
def handle_allow_nil_atomics(changeset, actor) do
changeset.atomics
Expand Down Expand Up @@ -2386,7 +2370,8 @@ defmodule Ash.Changeset do
end
end

defp add_atomic_validations(changeset, actor, opts) do
@doc false
def add_atomic_validations(changeset, actor, opts) do
eager? = Keyword.get(opts, :eager?, true)

changeset.atomic_validations
Expand Down

0 comments on commit c65f0c8

Please sign in to comment.