问题描述
我正在学习如何使用 Ecto 编写查询。我想从 has_many through 关系中过滤结果,如果可能的话,通过 Repo.all()
对数据库进行一次调用。
def users(organization_id) do
Repo.get(Organization,organization_id)
|> Ecto.assoc(:users)
end
def bookings(%{organization_id: organization_id}) do
Repo.get(Organization,organization_id)
|> Ecto.assoc(:bookings)
end
然后,重复使用上述之一:
def bookings(%{organization_id: organization_id,user_id: user_id}) do
Repo.get(Organization,organization_id)
|> Ecto.assoc(:bookings)
|> where([u],u.user_id == ^user_id)
end
但这不会按给定的 user_id 过滤结果。如何做呢?我错过了什么?
架构信息:
解决方法
您在追求Ecto.Query.subquery/2
。此外,Repo.get/1
已经对数据库执行了查询;在您的情况下,您应该构建查询,然后才执行它。
一个 Organization
可以有多个 Users
也就是说,user_id
表中没有 organizations
这样的字段。为了能够按 users
进行过滤,查询中需要有 users
。
我相信,按照这些思路是可行的(如果没有看到真正的模式,就不可能准确地判断。)
users =
from o in Organization,join: u in User,on: u.organization_id == o.id,where u.id == ^user_id
query =
from u in subquery(users),join: b in Booking,on: b.user_id == u.id
Repo.all(query)
或者,对于后者,可以使用 Ecto.assoc/2
:
users
|> Repo.all()
|> Ecto.assoc(:bookings)
|> Repo.all()