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:
https://kobrakai.de/kolumne/a-case-against-many_to_many/

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.

LostKobrakai

LostKobrakai

You don’t. Ecto will handle that for you when using the schema/changeset assoc handling. It’ll still be a transaction in the end.

Where Next?

Popular in Questions Top

aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
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
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
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
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New
jc00ke
Expanding on this topic: https://forum.elixirforum.net/t/map-typespec-question/19217 Let’s say I have a map with required and optional k...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
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
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement