How do I use a Union type as an action argument?

Given the following module and union type:
defmodule Insi.Subscriptions.SubscriptionPlan do
use Ash.Resource...

attributes do
...
attribute :features, {:array, Feature} do
public? true
default []
end
end
actions do
...
update :add_features do
argument :features, {:array, Feature}
manual AddFeatures
end
end

code_interface do
define :add_features, args: [:features]
end
end
defmodule Insi.Subscriptions.SubscriptionPlan do
use Ash.Resource...

attributes do
...
attribute :features, {:array, Feature} do
public? true
default []
end
end
actions do
...
update :add_features do
argument :features, {:array, Feature}
manual AddFeatures
end
end

code_interface do
define :add_features, args: [:features]
end
end
defmodule Insi.Subscriptions.Feature do
use Ash.Type.NewType,
subtype_of: :union,
constraints: [
types: [
installations: [
tag: :type,
tag_value: :installations,
type: :integer
# constraints: [min: 0]
],
...
end
defmodule Insi.Subscriptions.Feature do
use Ash.Type.NewType,
subtype_of: :union,
constraints: [
types: [
installations: [
tag: :type,
tag_value: :installations,
type: :integer
# constraints: [min: 0]
],
...
end
... how am I supposed to provide input to that SubscriptionPlan.add_features function? The following all blow up:
SubscriptionPlan.add_features([%Ash.Union{type: :installations, value: 1}]
SubscriptionPlan.add_features([%Ash.Union{type: :installations, content: 1}]
SubscriptionPlan.add_features([%{type: :installations, value: 1}]
SubscriptionPlan.add_features([%{type: :installations, content: 1}]
SubscriptionPlan.add_features([%Ash.Union{type: :installations, value: 1}]
SubscriptionPlan.add_features([%Ash.Union{type: :installations, content: 1}]
SubscriptionPlan.add_features([%{type: :installations, value: 1}]
SubscriptionPlan.add_features([%{type: :installations, content: 1}]
I think I've tried all those variations with string keys as well. I'm not even getting to the manual action before I keep getting this error:
%Ash.Error.Changes.InvalidArgument{field: :features, message: "is not a map", value: [%Ash.Union{value: 1, type: :installations}]...}
%Ash.Error.Changes.InvalidArgument{field: :features, message: "is not a map", value: [%Ash.Union{value: 1, type: :installations}]...}
Or sometimes the message is just "is invalid". Help?
Solution:
You can't use the tag/tag value for types that aren't maps
Jump to solution
7 Replies
ZachDaniel
ZachDaniel4mo ago
You should just be able to pass in integers Oh
Solution
ZachDaniel
ZachDaniel4mo ago
You can't use the tag/tag value for types that aren't maps
ZachDaniel
ZachDaniel4mo ago
Because there is nowhere to put the tag in You don't need the tag or tag value for integers generally
⿻ eileen
⿻ eileenOP4mo ago
Hmmmmm. Gonna play around with making it a map. I do need the tags because the union has multiple integer types Or maybe I can just do tuples ... {:installations, 2}
ZachDaniel
ZachDaniel4mo ago
You could do tuples or maps, yes
⿻ eileen
⿻ eileenOP4mo ago
Actually just removing the tag and tag_value totally fixed it Now I have %{type: :installations, value: 1} which is exactly what I wanted!
ZachDaniel
ZachDaniel4mo ago
🥳

Did you find this page helpful?