I am trying to write a macro + function to query on a field which is a map. Here is the schema:
schema "documents" do
field :content, :string
field :rendered_content, :string
field :title, :string
field :author_id, :integer
field :attributes, :map
And here is the code in module Query that I am struggling to write:
defmacro has_attribute_aux(key, value) do
quote do
fragment("SELECT id FROM documents WHERE attributes @> '{?: ?}'", unquote(key), unquote(value))
end
end
def has_attribute(query, key, value) do
from d in query,
where: has_attribute_aux(^key, ^value)
end
With it I would like to say
Document |> Query.is_public |> Repo.all
This way I would be able to compose with other queries that do work, as in
You haven’t exactly specified what is the problem - is there an error, is there something not working as expected?
Looking at the code, I see one thing - you can use parameters in queries as part of strings. You do that in '{?:?}' part. All postgres will see there is a string with question marks (actually dollars since it’s later converted by the adapter) - the point is, it won’t interpret this as a parameter. You either need to use postgres string concatenation (||) or use other operators than @>.