Skip to content

Instantly share code, notes, and snippets.

@knewter
Created October 8, 2015 12:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save knewter/7fa4c3bc93268490988a to your computer and use it in GitHub Desktop.
Save knewter/7fa4c3bc93268490988a to your computer and use it in GitHub Desktop.
ecto many to many query
# -*- c-basic-offset: 2; indent-tabs-mode: nil -*-
defmodule Score.ContactTest do
use Score.TestCase
@joe %{name: "joe", email: "joe@vipaar.com", sign_in_count: 0}
@joe_changeset User.changeset(%User{}, :create, @joe)
@bob %{name: "bob", email: "bob@vipaar.com", sign_in_count: 0}
@bob_changeset User.changeset(%User{}, :create, @bob)
setup do
joe = Repo.insert!(@joe_changeset)
bob = Repo.insert!(@bob_changeset)
joe_bob = %{user1_id: joe.id, user2_id: bob.id}
Contact.changeset(%Contact{}, :create, joe_bob)
|> Repo.insert!
{:ok, joe: joe, bob: bob}
end
test "finding a user's contacts", meta do
query = Score.Query.User.contacts(meta.joe)
contacts = Repo.all(query)
|> Enum.map(&(&1.name))
assert ^contacts = ["bob"]
end
end
defmodule Score.User do
has_many :contacts, Score.Contact, foreign_key: :user1_id
has_many :contact_connections, Score.Contact, foreign_key: :user2_id
end
defmodule Score.Query.User do
alias Score.Contact
alias Score.User
import Ecto.Query
def contacts(user=%User{}) do
from u in User,
join: c in assoc(u, :contacts),
inner_join: u1 in User, on: u1.id == c.user2_id,
where: c.user1_id == u.id,
select: u1
end
end
@happysalada
Copy link

happysalada commented Feb 25, 2018

Thanks for the gist!
I have one question though. Do you really need the where clause in the query-user (where: c.user1_id == u.id)? Isn't that statement already included in the
join: c in assoc(u, :contacts)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment