Экто присоединиться на нескольких условиях - PullRequest
1 голос
/ 06 марта 2020

Предполагается, что у меня есть три модели:

user: has_one wallet
wallet: belongs_to user
transactions: belongs_to wallet

Я пытаюсь получить все транзакции для данного пользователя. SQL Я могу использовать следующее:

SELECT
   * 
FROM
   transactions AS t 
   JOIN
      wallets AS w 
      ON w.user_id = 1 
      AND w.id = t.wallet_id

Сейчас в Ecto работает следующее, но оно не повторяет запрос выше:

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

Я не могу найти ни одного документы для создания ассоциаций с AND кейсами. Я пробовал:

join: w in (^wallet and assoc(t, :wallet)),

, но это приводит к ошибке компиляции. Цель состоит в том, чтобы написать этот запрос только для ассо c без ручных id соединений, чтобы позволить реляционной абстракции оставаться внутри моделей.

РЕДАКТИРОВАТЬ

, следуя предложению @ daniel и просматривая документы dynamic / 2 , мне удалось построить запрос с несколькими условиями соединения, предоставив дополнительные условия в 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

, которые были обнаружены, дают следующее:

SELECT t0."id" 
  FROM "transactions" AS t0 
  INNER JOIN "wallets" AS w1 
    ON (w1."id" = t0."wallet_id") 
    AND (w1."user_id" = $1)

1 Ответ

2 голосов
/ 06 марта 2020

Прежде всего, вы должны были уточнить, каковы ваши схемы, я буду считать:

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

Ваш запрос должен выглядеть следующим образом:

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
...