多个条件下的 Ecto join

Ecto join on multiple conditions

假设我有三个模型:

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)),

但这会导致编译错误。目标是仅在没有手动 id 连接的情况下在 assoc 上编写此查询,以使关系抽象保留在模型中。

编辑

按照@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" = )

首先你应该清楚你的模式是什么,我假设:

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