`many_to_many/3` will only save one ID in the join table

Hi,

Is there a common mistake people do when using many_to_many/3 that would result in only saving one of the IDs in the association?

I couldn’t find any so far, but wanted to make sure before inundating the list with my migrations and schemas. There are no errors, and inserting/updating would go through but only one ID would be saved from the assoc.

iex(15)> Repo.get_by(AccessNewsRole, role: "admin") \ 
...(15)> |> Repo.preload(:users) \                    
...(15)> |> Ecto.Changeset.change() \                 
...(15)> |> Ecto.Changeset.put_assoc(:users, [user]) \
...(15)> |> Repo.update()                             
{:ok, ...}
iex(9)>  admin_role = Repo.get_by(AccessNewsRole, role: "admin")
iex(10)> %User{} \
...(10) |> User.changeset(%{credential: %{username: "admin", password: "admin", password_length: 5}}) 
...(10) |> Ecto.Changeset.put_assoc(:roles, [admin_role])
...(10) |> Repo.insert()
{:ok, ...} 

… and this is the result from psql:

dev=# table users_roles;
 id |               user_id                | access_news_role_id |     inserted_at     |     updated_at      
----+--------------------------------------+---------------------+---------------------+---------------------
  1 | 3de70c77-505e-4f19-b453-604d1e1229e4 |                     | 2019-08-31 21:32:49 | 2019-08-31 21:32:49
  2 | 3de70c77-505e-4f19-b453-604d1e1229e4 |                     | 2019-08-31 21:34:41 | 2019-08-31 21:34:41

Thank you!
Attila

Short answer: yes, make sure that all _ids and field names are consistent through every schema involved. My mistake was that I used slightly different atoms in the join schema’s changeset when following the Join Schema Example in the many_to_many/3 docs.

1 Like