【发布时间】:2021-07-21 14:33:38
【问题描述】:
我正在尝试编写一个涉及动态表连接(照片到相册)的动态查询。我的第一次尝试仅适用于一对多(要放置的照片):
defmodule Test1 do
def filter_by_place_id(dynamic, id) do
dynamic([p], ^dynamic and p.place_id == ^id)
end
end
dynamic =
true
|> Test1.filter_by_place_id(248)
但这不适用于多对多领域。我认为这需要一个表连接。所以我的下一个尝试:
defmodule Test2 do
def filter_by_place_id({query, dynamic}, id) do
dynamic = dynamic([p], ^dynamic and p.place_id == ^id)
{query, dynamic}
end
def filter_by_album_id({query, dynamic}, id) do
query = join(query, :inner, [p], album in assoc(p, :albums), as: :x)
dynamic = dynamic([{:x, x}], ^dynamic and x.id == ^id)
{query, dynamic}
end
end
query = from(p in Photo)
{query, dynamic} =
{query, true}
|> Test2.filter_by_place_id(248)
|> Test2.filter_by_album_id(10)
|> Test2.filter_by_album_id(11)
但这失败了,因为绑定:x 是硬编码的,显然我不能重用它。但我需要一个绑定来确保 where 子句引用正确的连接。
但如果我尝试使用as: ^binding 而不是as :x,我会收到错误消息:
** (Ecto.Query.CompileError) `as` must be a compile time atom, got: `^binding`
(ecto 3.6.2) expanding macro: Ecto.Query.join/5
meow.exs:30: Test2.filter_by_album_id/2
所以我不确定从这里去哪里。是否可以为连接动态分配绑定?
【问题讨论】:
-
dynamic表达式允许用于join的:on选项——这可能值得尝试,因为正如您所注意到的,:as需要一个硬编码的命名绑定。