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

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
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
matt-savvy
Anyone here using Honeybadger? My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of Bandit.HTTPError...
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

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
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews