tomekowal

tomekowal

I’ve recently finished Designing Elixir Systems with OTP. It is an excellent book, and I highly recommend reading it!

Modelling the logic with pure data structures without using the DB is central to the architecture. In many cases, the core/entities have a relational structure. There is an excellent talk about it by Richard Feldman (the example is in Elm, but the same rules apply).

The problem is many to many relationships. An example from the above talk a student can attend many courses and courses have many students. In such situations, Richard recommended using dictionary (map in Elixir) id => %Student{}

That seems like a pretty clean idea, but I am not sure what to do with new records. Let’s say I want to add a new student to the course. I should generate a new id for that record. However, I should decouple the model from the DB, so I shouldn’t use DB id. But what should I use then? Other ids might be integers from the DB, and I don’t want to clash.

My end goal is a function like save(old_model, new_model) that checks what changes need saving and performs the writes.

I have a couple of ideas, but neither is very compelling.

Idea 1:
Using something like {:db, id} for stuff read from the DB and {:new, id} for new stuff. That makes the save function trivial. The downside is that I am leaking persistence details to the model/core.

Idea 2:
Introduce ids that are unrelated to DB. E.g. a student id might be a string "student-1". That would be unrelated to the DB id. When reading a particular set of courses, I would need to translate student.id: 237 to "student-1", student.id: 250 to `“student-2” and so on. That should work, but I need to keep the translations dictionary somewhere in case I need to update the student.

Do you have any other ideas for persistence? Or maybe an idea of using a map is not a good one, and I should the relationships differently?

Showing Posts 1 to 3

egze

egze

I would love to know as well. Paging @JEG2

JEG2

JEG2

Author of Designing Elixir Systems with OTP

My instinct is to favor ID’s unrelated to the database. It might be that you could get by with something as simple as :erlang.unique_integer/0, but my first choice would probably be to use UUID’s.

PostgreSQL supports using UUID’s as the primary key for a record. You can generate a UUID in your application and save it with the other fields. Put another way, you don’t have to have the database auto-assign the primary key (though it certainly will do that when desirable). So I don’t think any additional mapping would be required, if I’ve understood the constraints correctly.

tomekowal

tomekowal OP

Thank you! Yes, it looks like a helpful solution. This way core model does not need the DB for generating IDs and doesn’t require mapping.
After watching Richard’s talk, I thought integer keys are the only option. It never occurred to me that pairs of UUIDs can encode many-to-many relationships as good as integers.

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
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
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
mnkhod
So i have been using ash framework for a while and i love it. However currently the issue im having with ash framework is the error handl...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
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
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
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
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews