How to store structs to the database using Ash Framework and custom Ash.Type's

Hi there,
I’m working with ash now a couple of weeks and I’m quite a big fan :slight_smile: but now I’m struggling with a - so it seems - basic usecase.

I’m using the ash framework to manage my resources in the database (postgres).

I would like to store structs which are from a foreign library, namely instances of Ash.Query, to the datasbase. like:

attributes do
    attribute :query, Ash.Query
    ...
end

Of course using Ash.Query directly as type is not possible. My first intention was to solve this with a custom Ash.Type and use…

@impl true
  def storage_type, do: :map

…to tell the data layer I would like to store it as a :map on the data layer. but this did not work.

My question is: how can I define attributes on my ash resources, which are able to store structs of foreign libraries (structs which are NOT part of my code/project) and if it is only possible over custom Ash.Type’s, how can I serialize those structs properly, so I can write and read them like regular attributes?

Thanks for any hints :slight_smile:
Claudio

Well, I would very much advise against storing that kind of data in your database to be honest. But, if you must, use the :term type, which uses binary_to_term and term_to_binary to encode/decode to binary storage.

Why do you want to store an Ash.Query in a database?

Thx for the reply!

I got a data export feature. for each export (which runs async as oban jobs) I have to define specific filter criteria, so I can select data dynamically according to various situations.
to run, re-run and schedule those exports for later execution I have to - somehow - persist those filters/query criterias.

such a query/criteria basically looks like:

MyRecord
    |> Ash.Query.load(somestuff: [:id])
    |> Ash.Query.filter(
      somestuff.id == ^id and
        not is_nil(an_attribute) and
...

I honestly couldn’t find another solution to properly serialize those filters to re-use them later…

Best, C.

I would suggest using the map syntax that Ash filters support. For example:

Ash.Query.filter(%{id: %{eq: ^id}})

Then you can persist the map :slight_smile:

This would be awesome… :slight_smile: but how is it with relations?

like I do with

Ash.Query.load(somestuff: [:id])

I have to do queries over my related resources, can I dynamically load relations, according to a query?

Loading related data and referencing related data in filters is actually unrelated. You don’t need to load something to reference it. In the case of the map syntax, it would be %{some_stuff: %{id: %{eq: id}}}

1 Like

yes, right… will do it this way, thank you very much :slight_smile:

and thx for the awesome framework. it’s simply great :+1:

1 Like