fix: properly retain context from initial changeset in fully atomic changeset

This commit is contained in:
Zach Daniel 2024-05-03 12:14:08 -04:00
parent 9d7bb3b184
commit 2ab788fd35
4 changed files with 45 additions and 3 deletions

View file

@ -93,6 +93,14 @@ defmodule Ash.Actions.Destroy.Bulk do
changeset changeset
Ash.DataLayer.data_layer_can?(query.resource, :destroy_query) -> Ash.DataLayer.data_layer_can?(query.resource, :destroy_query) ->
opts =
Keyword.update(
opts,
:context,
%{private: query.context.private},
&Map.put(&1, :private, query.context.private)
)
Ash.Changeset.fully_atomic_changeset(query.resource, action, input, opts) Ash.Changeset.fully_atomic_changeset(query.resource, action, input, opts)
true -> true ->
@ -616,7 +624,7 @@ defmodule Ash.Actions.Destroy.Bulk do
resource = opts[:resource] resource = opts[:resource]
opts = Ash.Actions.Helpers.set_opts(opts, domain) opts = Ash.Actions.Helpers.set_opts(opts, domain)
{_, opts} = {context_cs, opts} =
Ash.Actions.Helpers.set_context_and_get_opts(domain, Ash.Changeset.new(resource), opts) Ash.Actions.Helpers.set_context_and_get_opts(domain, Ash.Changeset.new(resource), opts)
fully_atomic_changeset = fully_atomic_changeset =
@ -631,6 +639,14 @@ defmodule Ash.Actions.Destroy.Bulk do
{:not_atomic, "cannot atomically destroy a stream without a primary read action"} {:not_atomic, "cannot atomically destroy a stream without a primary read action"}
Ash.DataLayer.data_layer_can?(resource, :destroy_query) -> Ash.DataLayer.data_layer_can?(resource, :destroy_query) ->
opts =
Keyword.update(
opts,
:context,
%{private: context_cs.private},
&Map.put(&1, :private, context_cs.private)
)
Ash.Changeset.fully_atomic_changeset(resource, action, input, opts) Ash.Changeset.fully_atomic_changeset(resource, action, input, opts)
true -> true ->

View file

@ -54,6 +54,14 @@ defmodule Ash.Actions.Update.Bulk do
changeset changeset
Ash.DataLayer.data_layer_can?(query.resource, :update_query) -> Ash.DataLayer.data_layer_can?(query.resource, :update_query) ->
opts =
Keyword.update(
opts,
:context,
%{private: query.context.private},
&Map.put(&1, :private, query.context.private)
)
Ash.Changeset.fully_atomic_changeset(query.resource, action, input, opts) Ash.Changeset.fully_atomic_changeset(query.resource, action, input, opts)
true -> true ->
@ -801,7 +809,7 @@ defmodule Ash.Actions.Update.Bulk do
opts = Ash.Actions.Helpers.set_opts(opts, domain) opts = Ash.Actions.Helpers.set_opts(opts, domain)
read_action = get_read_action(resource, opts) read_action = get_read_action(resource, opts)
{_, opts} = {context_cs, opts} =
Ash.Actions.Helpers.set_context_and_get_opts(domain, Ash.Changeset.new(resource), opts) Ash.Actions.Helpers.set_context_and_get_opts(domain, Ash.Changeset.new(resource), opts)
fully_atomic_changeset = fully_atomic_changeset =
@ -816,6 +824,14 @@ defmodule Ash.Actions.Update.Bulk do
{:not_atomic, "cannot atomically update a stream without a primary read action"} {:not_atomic, "cannot atomically update a stream without a primary read action"}
Ash.DataLayer.data_layer_can?(resource, :update_query) -> Ash.DataLayer.data_layer_can?(resource, :update_query) ->
opts =
Keyword.update(
opts,
:context,
%{private: context_cs.context.private},
&Map.put(&1, :private, context_cs.context.private)
)
Ash.Changeset.fully_atomic_changeset(resource, action, input, opts) Ash.Changeset.fully_atomic_changeset(resource, action, input, opts)
true -> true ->

View file

@ -88,6 +88,7 @@ defmodule Ash.Actions.Update do
opts opts
|> Keyword.merge( |> Keyword.merge(
assume_casted?: true, assume_casted?: true,
context: changeset.context_changes,
notify?: true, notify?: true,
atomics: atomics:
Keyword.merge( Keyword.merge(

View file

@ -63,6 +63,7 @@ defmodule Ash.Changeset do
before_action: [], before_action: [],
before_transaction: [], before_transaction: [],
context: %{}, context: %{},
context_changes: %{},
defaults: [], defaults: [],
errors: [], errors: [],
params: %{}, params: %{},
@ -544,6 +545,7 @@ defmodule Ash.Changeset do
changeset = changeset =
resource resource
|> Ash.Changeset.new() |> Ash.Changeset.new()
|> Map.put(:context, opts[:context] || %{})
|> Map.put(:params, params) |> Map.put(:params, params)
|> Map.put(:action, action) |> Map.put(:action, action)
|> Map.put(:action_type, action.type) |> Map.put(:action_type, action.type)
@ -1349,7 +1351,7 @@ defmodule Ash.Changeset do
```elixir ```elixir
change fn changeset, _ -> change fn changeset, _ ->
Ash.Changeset.set_attribute(changeset, :score, changeset.data.score + 1) Ash.Changeset.change_attribute(changeset, :score, changeset.data.score + 1)
end end
``` ```
@ -3553,8 +3555,15 @@ defmodule Ash.Changeset do
def set_context(changeset, map) do def set_context(changeset, map) do
%{changeset | context: Ash.Helpers.deep_merge_maps(changeset.context, map)} %{changeset | context: Ash.Helpers.deep_merge_maps(changeset.context, map)}
|> store_context_changes(map)
end end
defp store_context_changes(%{phase: :pending} = changeset, map) do
%{changeset | context_changes: Ash.Helpers.deep_merge_maps(changeset.context_changes, map)}
end
defp store_context_changes(changeset, _), do: changeset
@type manage_relationship_type :: @type manage_relationship_type ::
:append_and_remove | :append | :remove | :direct_control | :create :append_and_remove | :append | :remove | :direct_control | :create