How do you filter data based on an union field?

I have this field in my resource:

    attribute :metadata, :union do
      public? true
      allow_nil? false

      constraints types: [
                    credit: [type: Types.Credit, tag: :type, tag_value: :credit],
                    one_time_use: [type: Types.OneTimeUse, tag: :type, tag_value: :one_time_use]
                  ]
    end

Here are the respective embeds:

defmodule Core.Marketplace.Payments.Product.Types.Credit do
  @moduledoc false

  use Ash.Resource,
    data_layer: :embedded

  attributes do
    attribute :skip_trace, :integer do
      allow_nil? false
      public? true
      default 0

      constraints min: 0
    end

    attribute :export, :integer do
      allow_nil? false
      public? true
      default 0

      constraints min: 0
    end
  end
end

and

defmodule Core.Marketplace.Payments.Product.Types.OneTimeUse do
  @moduledoc false

  use Ash.Resource,
    data_layer: :embedded

  attributes do
  end
end

Now I want to create an read action that will filter based on what the embed is.

I tried this:

    read :all_credits do
      filter expr(metadata.type == :credit)
    end

But this doesn’t seem to work. How can I achieve this without having to fallback to fragments?

IIRC it depends on the storage_type configured. you can do metadata[:value][:type] == :credit or metadata[:type] == :credit depending on the underlying data.

1 Like