Reputation: 2300
Assuming I have three models:
user: has_one wallet
wallet: belongs_to user
transactions: belongs_to wallet
I am trying to get all the transactions for a given user. The SQL I can use is the following:
SELECT
*
FROM
transactions AS t
JOIN
wallets AS w
ON w.user_id = 1
AND w.id = t.wallet_id
Now in Ecto the following works but it does not replicate the query above:
wallet = assoc(user, :wallet)
q = from t in Transaction,
join: w in ^wallet,
where: t.wallet_id == w.id,
order_by: [desc: t.id],
select: t
I can't find any docs for creating assocs with AND
cases. I've tried:
join: w in (^wallet and assoc(t, :wallet)),
but that results in a compile error. The goal would be to write this query on assoc only without manual id
joins to let the relational abstraction stay within the models.
EDIT
following @daniel's suggestion and looking at dynamic/2 docs, I managed to build the query with multiple join conditions, by supplying extra conditions in the on
:
id = user.id
q = from t in Transaction,
join: w in assoc(t, :wallet),
on: w.user_id == ^id,
order_by: [desc: t.id],
select: t
that snipped produces the following:
SELECT t0."id"
FROM "transactions" AS t0
INNER JOIN "wallets" AS w1
ON (w1."id" = t0."wallet_id")
AND (w1."user_id" = $1)
Upvotes: 4
Views: 2386
Reputation: 2554
I will assume:
schema "transactions" do
belongs_to :wallet, Wallet
timestamps()
end
schema "wallet" do
belongs_to :user, User
has_many :transactions, Transaction
timestamps()
end
schema "user" do
has_one :wallet, Wallet
timestamps()
end
Your query should look the following:
def user_transactions_query(id) do
from tr in Transaction,
join: wallet in assoc(tr, :wallet),
join: user in assoc(wallet, :user),
where: user.id == ^id
end
Upvotes: 4