这是原始streamSupplier.get().findFirst().get()
Ecto.Query
重构:
def by_id(user_id, company_id, asset_id) do
# section 1
from a in Asset,
# section 2
join: acl in AccessList, on: acl.asset_id == a.id,
join: c in Company, on: acl.company_id == c.id,
join: u in User, on: acl.user_id == u.id,
# section 3
where: u.id == ^user_id and c.id == ^company_id
# section 4
and a.id == ^asset_id,
# section 5
select: %{
asset_name: a.asset_name,
asset_id: a.id,
inserted_at: a.inserted_at
},
# section 6
group_by: a.id,
# section 6
order_by: a.id
end
然后我就像这样连接:
def by_query do
from a in Asset
end
def by_join(query) do
from a in query,
join: acl in AccessList, on: acl.asset_id == a.id,
join: c in Company, on: acl.company_id == c.id,
join: u in User, on: acl.user_id == u.id
end
def by_where_user(query, user_id) do
query = from q in query
query
|> where([u], u.id == ^user_id)
end
def by_where_company(query, company_id) do
query = from q in query
query
|> where([c], c.id == ^company_id)
end
def by_where_asset(query, asset_id) do
query = from q in query
query
|> where([a], a.id == ^asset_id)
end
def by_select(query) do
from a in query,
select: %{
asset_name: a.asset_name,
asset_id: a.id,
inserted_at: a.inserted_at
},
group_by: a.id,
order_by: a.id
end
现在它不起作用。
生成的查询不同,我可以看到问题与 query = by_query
|> by_join
|> by_where_user(user_id)
|> by_where_company(company_id)
|> by_where_asset(asset_id)
|> by_select
子句有关。
where
SELECT a0."asset_name", a0."id", a0."inserted_at"
FROM "assets" AS a0
INNER JOIN "access_lists" AS a1 ON a1."asset_id" = a0."id"
INNER JOIN "companies" AS c2 ON a1."company_id" = c2."id"
INNER JOIN "users" AS u3 ON a1."user_id" = u3."id"
WHERE (a0."id" = $1)
AND (a0."id" = $2)
AND (a0."id" = $3)
GROUP BY a0."id"
ORDER BY a0."id" [3349, 1, 5]
应为Where
,a0
和c2
这是基于: https://hexdocs.pm/ecto/Ecto.Query.html#module-query-bindings
答案 0 :(得分:2)
问题在于三个by_where_*
条款。没有状态,因此Ecto
没有机会记住在其他函数中如何调用选择。处理它的最简单方法是使用另一个关联结束:
def by_where_user(query, user_id) do
from q in query
|> where([result], result.user_id == ^user_id)
end
def by_where_company(query, company_id) do
from q in query
|> where([result], result.company_id == ^company_id)
end
def by_where_asset(query, asset_id) do
from q in query
|> where([result], result.asset_id == ^asset_id)
end