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
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
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
It’s totally doable… but not with many_to_many.
With two has_many, and one should be has_many through.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









