Ash FrameworkAF
Ash Frameworkโ€ข3y agoโ€ข
7 replies
morfertaw

Identity on `attribute :some_attribute, {:array , EmbeddedResource}`

So if I have the following resource.
defmodule Resource do
...
  actions do
    defaults [:create, :read, :update, :destroy]
  end

  attributes do
    ...
    uuid_primary_key :id

    attribute :some_attribute, {:array, EmbeddedResource}
    ...
  end

  identities do
    ...
    identity :unique_some_attribute, [:some_attribute]
    ...
  end
end

And the following embedded resource.
defmodule EmbeddedResource do
  use Ash.Resource,
    data_layer: :embedded

  attributes do
    attribute :key, :string do
      constraints trim?: true
      allow_nil? false
    end

    attribute :value, :string do
      constraints trim?: true
      allow_nil? false
    end
  end

  identities do
    identity :unique_key, [:key]
  end
end

If I do the following changeset twice.
Resource
|> Ash.Changeset.for_create(:create, %{})
|> Api.create()

It succeeds once and then fails a second time, which is as expected. The :unique_some_attribute identity prevents two records with some_attribute: nil. However If the next changeset is repeated twice.
Resource
|> Ash.Changeset.for_create(:create, %{some_attribute: [%{key: "color", value: "ash"}]})
|> Api.create()

Two resources with the same :some_attribute field are created. I had hoped this to be prevented by the :unique_some_attribute identity.
The resulting records look something like the following.
%Resource<
  ...
  id: "uuid_1",
  some_attribute: [
    %EmbeddedResource<
      ...
      autogenerated_id: "autogenerated_uuid_1",
      key: "color",
      value: "ash"
    >
  ]
>

%Resource<
  ...
  id: "uuid_2",
  some_attribute: [
    %EmbeddedResource<
      ...
      autogenerated_id: "autogenerated_uuid_2",
      key: "color",
      value: "ash"
    >
  ]
>

I assume the autogenerated_id fields being unique is preventing the desired outcome. Would that work and can they be disabled?
Was this page helpful?