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
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
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
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
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
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
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
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
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

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews