I’ve been working on some code, it’s like as follows -
defmodule SomeMod do
defmacro check_and_replace(username) do
quote do
unquote(String.replace(username, ~r/\./, ""))
end
end
def someFn(username) do
query =
from u in User,
where: ([u], check_and_replace(u.username) == check_and_replace(^username)),
select: u.username
case Repo.one(query) do
nil -> true
_ -> false
end
end
end
The where line here seems like it’s trying to be the macro form but it’s punctuated like the function form. The ([u], ...) part is what the compiler’s complaining about.
HOWEVER
This part isn’t going to work as desired either:
defmacro check_and_replace(username) do
quote do
unquote(String.replace(username, ~r/\./, ""))
end
String.replace is an Elixir function, not a SQL one.
There’s a good reason for that. You cannot do that. Ecto queries are a DSL for SQL queries, which are sent to and executed in the database. The database has no idea about elixir. Either figure out how to do what you need to do with sql in the db or postprocess results after the query ran with Elixir.
No idea how to fix your orginal code in the format you are trying to use, but if you just want to check for existing matching values you can do below btw:
def search_users(query) do
Repo.one(
from u in User,
where: fragment("lower(?) = lower(?)", u.username, ^query)
)
end
This fragment basically converts your query to lowercase, and looks for a matching lowercase u.username
Do you actually want to replace names as well? If so, why not just query the name to return the ID, then update the name for the matching ID? I’m a bit lost as to why you are trying to search and replace.
At best you’d normalize the username on insert and put that in a separate column next to the unaltered one. Then you don’t need to do that over and over again whenever you’re comparing to the username you got on a request. Normalizing the requested username can be done in elixir before placing it on the query.
@GazeIntoTheAbyss yes, they are two different links, but pointing to same page. I’m building an API (i.e., I’m not using phoenix live view or templates). The frontend of the app resides on a different server.