如何将大 Ecto.Query 分成小块?
How to break a large Ecto.Query in smaller pieces?
有没有一种方法可以将此查询分解成不同的部分并根据需要构建它。我需要这个的不同部分。
查询工作正常,但是复制和粘贴它只是为了改变不同的部分不是很干净的方法。我用 #
指出了我需要重用的块。
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
来自 Ecto.Query
文档:
Ecto queries are composable. For example, the query above can actually be defined in two parts:
# Create a query
query = from u in User, where: u.age > 18
# Extend the query
query = from u in query, select: u.name
也就是说,您可能会:
q1 = from a in Asset
q2 = from a in q1,
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
等等
我已经 written 详细介绍了如何编写 Ecto 查询。当您将此技术与模式匹配结合使用时,您可以非常轻松地编写复杂的查询。
下面是一个基于公司查询用户的系统示例。
def list_users(_user, "admin", params) do
User
|> filter_by_params(params |> Map.to_list())
end
def filter_by_params(query, params) do
Enum.reduce(params, query, fn
tuple, query ->
filter_dataset(query, tuple)
end)
end
def filter_dataset(query, {"company_id", company_id}) do
query
|> join(:inner, [u], c in assoc(u, :company))
|> where([_u, ..., company], company.id == ^company_id)
end
def filter_dataset(query, _no_matching_tuple), do: 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
来自 Ecto.Query
文档:
Ecto queries are composable. For example, the query above can actually be defined in two parts:
# Create a query query = from u in User, where: u.age > 18 # Extend the query query = from u in query, select: u.name
也就是说,您可能会:
q1 = from a in Asset
q2 = from a in q1,
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
等等
我已经 written 详细介绍了如何编写 Ecto 查询。当您将此技术与模式匹配结合使用时,您可以非常轻松地编写复杂的查询。
下面是一个基于公司查询用户的系统示例。
def list_users(_user, "admin", params) do
User
|> filter_by_params(params |> Map.to_list())
end
def filter_by_params(query, params) do
Enum.reduce(params, query, fn
tuple, query ->
filter_dataset(query, tuple)
end)
end
def filter_dataset(query, {"company_id", company_id}) do
query
|> join(:inner, [u], c in assoc(u, :company))
|> where([_u, ..., company], company.id == ^company_id)
end
def filter_dataset(query, _no_matching_tuple), do: query