Ash FrameworkAF
Ash Framework3y ago
21 replies
Robert Graff

Applying constraints to embedded union types

I have a resource when an embedded array of union types:

defmodule MyApi.Package
  attributes do
    ...
    attribute :options, {:array, PackageOption}, allow_nil?: false
  end
end


defmodule MyApi.PackageOption do
  use Ash.Type.NewType,
    subtype_of: :union,
    constraints: [
      types: [
        boolean: [
          type: MyApi.PackageOption.Boolean
          tag: :type,
          tag_value: :boolean
        ],
        string: [
          type: MyApi.PackageOption.String
          tag: :type,
          tag_value: :string
        ]
      ]
    ]
end

defmodule MyApi.PackageOption.Boolean do
  use Ash.Resource, data_layer: :embedded

  attributes do
    uuid_primary_key :id
    attribute :key, :ci_string, allow_nil?: false, constraints: [match: ~r/^[a-z0-9-]+$/]
    attribute :value, :boolean
    attribute :type, :atom, constraints: [one_of: [:boolean]]
    attribute :enabled, :boolean, allow_nil?: false
  end

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

defmodule MyApi.PackageOption.String do
  use Ash.Resource, data_layer: :embedded

  attributes do
    uuid_primary_key :id
    attribute :key, :ci_string, allow_nil?: false, constraints: [match: ~r/^[a-z0-9-]+$/]
    attribute :value, :text
    attribute :type, :atom, constraints: [one_of: [:string]]
    attribute :enabled, :boolean, allow_nil?: false
  end

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


When doing a create or update on the parent (MyApi.Package) with an option that has an invalid key (see constraint), it's not returning %Ash.Error.Invalid{} as expected. I've tried applying a validation in lieu of an attribute constraint, but the validation is never called.

Additionally, the identity is not enforced.
Was this page helpful?