alexslade

alexslade

We’ve just started using paper_trail for versioning some resources, and we want to reference those in various places. I’d like to know if others have trodden this path before.

Tl;Dr

Is there an idiomatic ash way to fetch a specific guid for a version and get back hydradeted, normal ash resource struct, with version information?

(I’m going to continue researching and may self-update if I find something. Hopefully this is still a useful log for other people in the future)

More context

I’ve considered a couple of approaches and wondered if others have trodden this path before. I’m going to explain my full thinking in case it’s useful to others coming past, but you can skip to the end for my questions.

Our app is essentially a content editor, allowing users to write documents. Each document references things like images, text snippets, etc. We’ve added versioning to those resources, and now we’re updating these internal references to be version-aware.

(We use guid resource ids)

We want a document to pin e.g. “Image of a cat - v1”. Now when the CMS updates the image (e.g. updates the alt text) the document is aware that it is holding an outdated version, and should nudge the user to update the image from the CMS copy.

Idea 1 - Continue to reference the resource only

Breaking problem: we can’t pin to a specific version, so this already doesn’t work.

Idea 2 - Reference the version only

Pros: we explicitly reference version. We only need to store 1 guid.

Cons: more lookups and extra logic to get the full picture (resource with version information).

Questions: I bet there’s a clever ash way to always return resource lookups with embedded version information, but I haven’t found it yet.

3 - Create a hybrid reference, {resource, version}

Store some hybrid ID that includes both the resource and version ID.

Pros: we have both guids, we can directly work with either. More direct representation in the database (though with guids this doesn’t matter, we are planning to switch to stripe-style object ids that would have useful prefixes on ids).

Cons: we have to store both guids! Same amount of work and lookups.

Showing Posts 1 to 4

zachdaniel

zachdaniel

Creator of Ash

There is nothing built in for that, no. Depending on which versioning strategy its harder or easier, for example if you use the :snapshot strategy then you should theoretically be able to hydrate a resource with essentially an Enum.reduce, getting the corresponding attribute via Ash.Resource.Info.attribute, using Ash.Type.cast_stored(type, value, constraints) on each value, and returning a struct w/ those values.

One thing you might consider doing is making a calculation that does this logic, so you can do

thing |> Ash.load(at_version: %{version: <version_id>})

or maybe

thing |> Ash.load(version_as_of: %{timestamp: <datetime>})
alexslade

alexslade OP

I’ll explore snapshot and full_diff and see what fits our case best.

Thanks for the pointer and calculation tip :heart:

alexslade

alexslade OP

@zachdaniel we’ve got a basic setup working now with “hydrated” resources, but it feels a bit brittle: it’s re-using Ash structs for items that aren’t “real” ash resource instances, and it feels like that could easily be mistaken for a real instance and cause some trouble. I’m thinking of ways to make it more idiomatic.

If I were to PR a change, would this idea align with Ash goals?

Added support for some kind of “read only” meta_data flag on resources, so that extensions like PaperTrail can create temporary copies of resources that were hydrated from versions, and can be read or referenced, but don’t get confused with a copy of a loaded version from the DB. And validation or something similar that would prevent write actions with that struct.

(This is deeper in the Ash internals than I’m familiar with, so I wanted to ask for direction first)

zachdaniel

zachdaniel

Creator of Ash

Hmm…I’m not sure if this would make sense to have in Ash core. The records it produces could have a metadata in __metadata__ set with Ash.Resource.set_metadata and you could have logic that prevents using them in actions?

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews