defmodule Ash.Test.Actions.HasManyTest do @moduledoc false use ExUnit.Case, async: true require Ash.Query defmodule Comment do use Ash.Resource, data_layer: Ash.DataLayer.Ets actions do defaults [:create, :read, :update, :destroy] end ets do private? true end attributes do uuid_primary_key :id attribute :post_id, :uuid attribute :content, :string end end defmodule OtherRegistry do use Ash.Registry entries do entry Comment end end defmodule OtherApi do use Ash.Api resources do registry OtherRegistry end end defmodule Post do @moduledoc false use Ash.Resource, data_layer: Ash.DataLayer.Ets ets do private?(true) end actions do defaults [:create, :read, :update, :destroy] update :add_comment do accept [] argument(:comment, :map, allow_nil?: false) change manage_relationship(:comment, :comments, on_no_match: :create, on_match: :update) end update :delete_comment do accept [] argument(:comment, :map, allow_nil?: false) change manage_relationship(:comment, :comments, on_no_match: :error, on_match: :destroy) end end attributes do uuid_primary_key :id attribute :title, :string end relationships do has_many :comments, Comment do destination_attribute :post_id api OtherApi end end end defmodule Registry do @moduledoc false use Ash.Registry entries do entry(Post) end end defmodule Api do @moduledoc false use Ash.Api resources do registry Registry end end test "destroyed items are removed from the relationship" do post = Post |> Ash.Changeset.for_create(:create, %{ title: "buz" }) |> Api.create!() post = post |> Ash.Changeset.for_update(:add_comment, %{ comment: %{content: "foo"} }) |> Api.update!() assert length(post.comments) == 1 post = post |> Ash.Changeset.for_update(:add_comment, %{ comment: %{content: "bar"} }) |> Api.update!() assert length(post.comments) == 2 post = post |> Ash.Changeset.for_update(:delete_comment, %{ comment: Enum.at(post.comments, 0) }) |> Api.update!() assert length(post.comments) == 1 end end