gonzofish

gonzofish

Ecto: how to join three tables?

I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing something.

  • I have 3 tables
    • users
    • teams
    • roles
  • The set of roles is a static set of 9 roles
  • A user belongs to many teams with a single role

If I was writing SQL by hand, I think the query would be something like:

SELECT *
FROM group_user_roles gur 
JOIN teams t
ON t.id = gur.team_id
JOIN roles r
ON r.id = gur.role_id
JOIN users u
ON u.id = gur.user_id

Or something like that…

Does anyone know how would I go about achieving something like this through Ecto?

Thanks for any responses/views!

Most Liked

kelvinst

kelvinst

The function you’re looking for is this: https://hexdocs.pm/ecto/Ecto.Query.html#join/5.

To write the same SQL you have would be something like:

Repo.all from gur in "group_user_roles", 
  join: t in "teams", on: t.id == gur.team_id,
  join: r in "roles", on: r.id == gur.role_id,
  join: u in "users", on: u.id == gur.user_id

That would have the same result of the select, and it does not use any Ecto.Schema. If you have the schemas like:

defmodule GroupUserRole do
  schema "group_user_roles" do
    belongs_to :user, User
    belongs_to :role, Role
    belongs_to :team, Team
  end
end

defmodule User do
  schema ...
end

defmodule Team do
  schema ...
end

defmodule Role do
  schema ...
end

You can do a simpler query:

Repo.all from gur in GroupUserRole, 
  join: t in assoc(:team),
  join: r in assoc(:role),
  join: u in assoc(:user)
13
Post #2
pystar

pystar

The quoted didn’t work for me (2021).
This did:

You can do a simpler query:

Repo.all from gur in GroupUserRole, 
  join: t in assoc(gur, :team),
  join: r in assoc(gur, :role),
  join: u in assoc(gur, :user)

Anyone know why? Syntax change? I am a newbie so pardon my question.

gonzofish

gonzofish

@kelvinst thanks for the reply! i’ll give that a shot

kelvinst

kelvinst

Sorry I took so long to answer. So basically it was not working for you because I typed my example straight in here and forgot to add the first argument of the assoc as you did. So that’s it, your version is actually the right one :smiley:

gdub01

gdub01

Yeah I guess it’s a little less convenient to access than just have user.team.role… but it’s more flexible. To be honest I forget where I was even using that code so I can’t quite remember how I liked accessing those fields.

GitHub - woylie/flop: Filtering, ordering and pagination for Ecto is an interesting library that enables queries on joins pretty easily. I’m not sure if that’d be relevant if you want to query things a little more conveniently.

Where Next?

Popular in Questions Top

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
Tee
can someone please explain to me how Enum.reduce works with maps
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
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
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
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
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
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
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

Other popular topics Top

Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New

We're in Beta

About us Mission Statement