I’ve got a dynamic ecto query builder that dynamically builds queries based on JSON filters. Apart from static values included in the filters, filters can also include special values, like __CURRENT_USER__, which is converted by the filter generator to a fragment calling a database function—specifically, a postgres function called app_public.current_user_id(). So, for example, a filter condition that looks like this:
%{
value: ["__CURRENT_USER__"],
metadata: %{},
field: "__createdBy__",
keyword: "in",
}
Generates a query that looks like this:
#Ecto.Query<from o0 in AboardEx.Repo.Object, prefix: "app_public",
where: o0.created_by in ^[dynamic([], fragment("app_public.current_user_id()"))]>
Which is exactly what I want it to look like. But when I run the query w/Repo.all(), I get the following error:
** (Ecto.Query.CastError) lib/aboard_ex/repo/filter.ex:262: value `[dynamic([], fragment("app_public.current_user_id()"))]` in `where` cannot be cast to type {:in, :binary_id} in query:
from o0 in AboardEx.Repo.Object,
prefix: "app_public",
where: o0.created_by in ^[dynamic([], fragment("app_public.current_user_id()"))],
select: o0
(elixir 1.16.1) lib/enum.ex:2528: Enum."-reduce/3-lists^foldl/2-0-"/3
(elixir 1.16.1) lib/enum.ex:1826: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
(elixir 1.16.1) lib/enum.ex:2528: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto 3.11.1) lib/ecto/repo/queryable.ex:214: Ecto.Repo.Queryable.execute/4
(ecto 3.11.1) lib/ecto/repo/queryable.ex:19: Ecto.Repo.Queryable.all/3
iex:29: (file)
I understand the error, but I’m wondering if there’s anyway to work around this—short of converting the __CURRENT_USER__ string to it’s ID in the elixir code rather than using the fragment. In postgres, as far as I can tell, this would be perfectly valid code. E.g.:
SELECT * into _objects
FROM app_public.objects
WHERE created_by IN (app_public.current_user_id(), 'SOME-OTHER-ID');
Is it possible to achieve this with Ecto?






















