How to use ref/2 to generate a path to an union embeded (jsonb) object?

In my code I’m using ref/2 from Ash.Expr to generate dynamic paths for resources, like this:

To access some.path.some_field:

expr(^ref([:some, :path], :some_field) in ["something"])

which will generate this query:

{:_ref, [:some, :path], :some_field} in ["something"]

This works great with relationships, but, if the path is actually inside am embed (jsonb) or in my case, I want to access a field in an union, then this wont work.

For example, if I have this:

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

      constraints types: [
                    credits: [type: Types.Credits, tag: :type, tag_value: :credits],
                    open_title: [type: Types.OpenTitle, tag: :type, tag_value: :open_title]
                  ]
    end

Then I want to access it using metadata[:type], but, if I use:

expr(^ref([:metadata], :type) in [:credits])

Then it will fail since it will try to access the field using metadata.type instead of metadata[:type].

What should I use instead of ref/2 to get the correct query in this case?

Found it!

I need to use get_path/2 to achieve that. so, for example, if the path I want to get is metadata["type"], then I can write it like this:

expr(get_path(^ref(:metadata), ["type"]) in ["something"])

You can also define a calculation that is like a shortcut for the deeply nested field and then use that.

Depending on the use case that might also be easier to read.

Yep, that is what I would do if it was something more specific, but in this case is for a library that I maintain that would receive the path as lists instead of expressions that’s why I’m manually converting them to query afterwards :slight_smile: