I have a resource with an attribute that is an array of strings. Calculations on these arrays seem inconsistent:
attribute :tags, {:array, :string}, allow_nil?: false
Some calculations:
calculate :num_tags, :integer, expr(length(tags))
calculate :all_tags, :string, expr(string_join(tags, ", "))
calculate :reverse_tags, {:array, :string}, expr(lazy({__MODULE__, :reverse, [tags]}))
Loading :num_tags
works, but loading :all_tags
raises:
(Protocol.UndefinedError) protocol Enumerable not implemented for drivers of type Ash.Query.Ref (a struct)
If I substitute a literal list of strings the expression works.
When I include the third calculation it fails to compile, undefined variable “tags”, but if I wrap it to be [expr(tags)]
then it compiled but I’m back to the Protocol.UndefinedError above, and yet it works with a literal list of strings.
It looks like some calculations on compound attributes don’t work. I’m using ash 2.21.12 and ash_postgres 1.5.23.
Someone actually reported this issue to me just last night, will be looking into it shortly. It’s a bug specifically with string_join
, somewhere it is expecting to receive a literal list of strings and isn’t handling the case that it’s given an expression. I will update you if/when I fix it. Are you on 3.0? EDIT: nvm you explained in your question what version you were on.
I guess the lazy({MFA})
must suffer from the same problem. That’s what I’m really trying to use as the operation is more like the second list of strings carries instructions to apply to the first list. I don’t think I can do that in Ash expressions so the escape hatch is what I’m really interested in.
Thanks as always @zachdaniel for looking into it!
I’ve pushed a fix for the string_join
calculation only working with literal values to both the latest 3.0 release candidate and the 2.0 branch.
We’ll need to look into the lazy
separately, since I’m not quite sure how related or unrelated to this issue it is. Lets start a new GH issue or thread if you still have issues after upgrading.
1 Like