tomekowal

tomekowal

Modelling application core with relational entities

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?

Marked As Solved

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.

Where Next?

Popular in Questions Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: <h1>Create Post</h1> <%= ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 47930 226
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New

We're in Beta

About us Mission Statement