silverdr

silverdr

Many to many – once again… (extra data on the join table)

In a many-to-many relationship, let’s say users and chatrooms for a good example, there’s a join table users_chatrooms and appropriate Ecto.Schema entries:

many_to_many :users, PhxApp.Accounts.User, join_through: PhxApp.Accounts.UserChatroom

and

many_to_many :chatrooms, PhxApp.Chatrooms.Chatroom, join_through: PhxApp.Accounts.UserChatroom

but let’ say I need to store additional information like whether given user is the “owner” or a “moderator” of a given chatroom and the obvious place to store this kind of info is on the join table. So I have a role_id column on that table meant to store this information. Now, how does one do the CRUD stuff in such setup? Let’s say in the simplest case first - the user who creates the chatroom is always the owner but the role_id has to be set explicitly rather than being a DB default?

Most Liked

LostKobrakai

LostKobrakai

You can find some docs here: Ecto.Schema — Ecto v3.7.1

I blogged about a bit of the background to why things are the way they are:

LostKobrakai

LostKobrakai

So the user already exists. So essentially we don’t need to handle the many to many anymore to begin with given you’re not actually affecting both ends. All you insert is the chatroom and the first user of it:

%Chatroom{name: "chatroom_name", chatroom_users: [%{user_id: user.id, role: :owner}]} |> Repo.insert()

One important thing ecto doesn’t do, but people somehow expect is having an API to create relationships to already existing records. Just set the :record_id on wherever you need it. There is Ecto.build_assoc, but usually it doesn’t make things simpler.

kokolegorille

kokolegorille

It’s totally doable… but not with many_to_many.

With two has_many, and one should be has_many through.

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
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
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
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New

Other popular topics Top

New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
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
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
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
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
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

We're in Beta

About us Mission Statement