Ecto 在多种条件下加入

问题描述 投票:0回答:1

假设我有三个模型:

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

但这会导致编译错误。目标是仅在 assoc 上编写此查询,而无需手动

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)
elixir phoenix-framework ecto
1个回答
4
投票

我假设:

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
© www.soinside.com 2019 - 2024. All rights reserved.