是否可以模式匹配Ecto fragment
?
Place
保存特定Visitors
的次数 - 始终相同 Visitor
保存了Place
- true
/ false
Visitor's
ID是否在保存此地点的Visitors
ID列表中我可以通过模式匹配来实现吗?
defmacrop saved_count(place_id) do
quote do
fragment(
"(SELECT count(id) FROM \"saved_places\" WHERE place_id = ?)",
unquote(place_id)
)
end
end
defmacrop saved_by_visitor?(place_id, saved_by_visitor)
when is_boolean(saved_by_visitor) do
quote do
fragment(
"(?)::BOOLEAN",
^unquote(saved_by_visitor)
)
end
end
defmacrop saved_by_visitor?(place_id, visitor_id) do
{:ok, binary_visitor_id} = Ecto.UUID.dump(visitor_id)
quote do
fragment(
"(SELECT ? = ANY(array_agg(visitor_id)) FROM \"saved_places\" WHERE place_id = ?)",
^binary_visitor_id,
unquote(place_id)
)
end
end
defp add_extra_fields(query, saved_by_visitor) do
from places in query,
group_by: places.id,
select: %{places |
saved_count: saved_count(places.id),
saved_by_visitor: saved_by_visitor?(places.id, saved_by_visitor)
}
end
错误在于:
no match of right hand side value: :error
因为我无法直接将saved_by_visitor
值传递给宏。
编辑:
我提出以下问题:
defmacrop saved_by_visitor?(place_id, saved_by_visitor)
when is_boolean(saved_by_visitor) do
quote do
fragment(
"(?)::BOOLEAN",
^unquote(saved_by_visitor)
)
end
end
defmacrop saved_by_visitor?(place_id, visitor_id) do
quote do
fragment(
"(SELECT ? = ANY(array_agg(visitor_id)) FROM \"saved_places\" WHERE place_id = ?)",
^Ecto.UUID.dump(unquote(visitor_id)),
unquote(place_id)
)
end
end
defp add_extra_fields(query, saved_by_visitor) do
from places in query,
group_by: places.id,
select: %{places |
saved_count: saved_count(places.id),
saved_by_visitor: saved_by_visitor?(places.id, saved_by_visitor)
}
end
但是当然还有保护和模式匹配的问题。