Skip to content

Commit

Permalink
fix - handle soft destroys with manage_relationship (#1659)
Browse files Browse the repository at this point in the history
  • Loading branch information
lardcanoe authored Dec 14, 2024
1 parent 867a84b commit 4815bb1
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
3 changes: 3 additions & 0 deletions lib/ash/actions/managed_relationships.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1723,6 +1723,9 @@ defmodule Ash.Actions.ManagedRelationships do
{:ok, notifications} ->
{:cont, {:ok, current_value, notifications ++ all_notifications}}

{:ok, _soft_destroyed_record, notifications} ->
{:cont, {:ok, current_value, notifications ++ all_notifications}}

{:error, error} ->
{:halt, {:error, error}}
end
Expand Down
78 changes: 76 additions & 2 deletions test/manage_relationship_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@ defmodule Ash.Test.ManageRelationshipTest do

create :create do
accept [:name]
argument :related_resource, :map, allow_nil?: false
argument :related_resource, :map
argument :other_resources, {:array, :map}

change manage_relationship(:related_resource, :related_resource, type: :create)
change manage_relationship(:other_resources, type: :direct_control)
end

update :update do
require_atomic? false
accept [:name]
argument :related_resource, :map, allow_nil?: false
argument :related_resource, :map
argument :other_resources, {:array, :map}

change manage_relationship(:related_resource, :related_resource, type: :direct_control)
change manage_relationship(:other_resources, type: :direct_control)
end
end

Expand All @@ -34,6 +38,8 @@ defmodule Ash.Test.ManageRelationshipTest do
relationships do
has_one :related_resource, Ash.Test.ManageRelationshipTest.RelatedResource,
destination_attribute: :parent_resource_id

has_many :other_resources, Ash.Test.ManageRelationshipTest.OtherResource
end
end

Expand Down Expand Up @@ -65,6 +71,33 @@ defmodule Ash.Test.ManageRelationshipTest do
end
end

defmodule OtherResource do
use Ash.Resource,
domain: Ash.Test.Domain,
data_layer: Ash.DataLayer.Ets,
fragments: [RelatedResourceFragment]

actions do
defaults [:read, create: :*, update: :*]

destroy :archive do
primary? true
soft? true
change set_attribute(:archived_at, &DateTime.utc_now/0)
end
end

attributes do
uuid_primary_key :id
attribute :required_attribute, :string, allow_nil?: false, public?: true
attribute :archived_at, :utc_datetime_usec
end

relationships do
belongs_to :parent_resource, ParentResource
end
end

test "errors have the proper path set on them" do
assert {:error,
%Ash.Error.Invalid{
Expand Down Expand Up @@ -110,4 +143,45 @@ defmodule Ash.Test.ManageRelationshipTest do

assert parent.related_resource.required_attribute == "other_string"
end

test "can create and destroy arrays" do
assert {:ok, parent} =
ParentResource
|> Ash.Changeset.for_create(:create, %{
name: "Test Parent Resource",
other_resources: [
%{required_attribute: "first"},
%{required_attribute: "second"}
]
})
|> Ash.create!()
|> Ash.load(:other_resources)

assert Enum.map(parent.other_resources, & &1.required_attribute) |> Enum.sort() == [
"first",
"second"
]

other_resources = Enum.reject(parent.other_resources, &(&1.required_attribute == "first"))

assert {:ok, updated_parent} =
parent
|> Ash.Changeset.for_update(:update, %{
other_resources: other_resources
})
|> Ash.update!()
|> Ash.load(:other_resources)

# Since we did a soft destroy, we should still have all other resources
assert Enum.map(updated_parent.other_resources, & &1.required_attribute) |> Enum.sort() == [
"first",
"second"
]

first_other = Enum.find(updated_parent.other_resources, &(&1.required_attribute == "first"))
assert not is_nil(first_other.archived_at)

second_other = Enum.find(updated_parent.other_resources, &(&1.required_attribute == "second"))
assert is_nil(second_other.archived_at)
end
end

0 comments on commit 4815bb1

Please sign in to comment.