Rewriting this where using private fn

Thanks everyone for the help. This my final version


def list_items(%{matching: name}) when is_binary(name) do
    Item
    # |> where([m], ilike(m.name, ^"%#{name}%"))
    |> search(name)
    |> Repo.all()
  end

  defp search(_query, name) do
    query = from(query in Item)

    query
    |> where([t], ilike(t.name, ^"%#{name}%"))
  end
1 Like

You’re overthinking my response, I’m saying you literally can just leave out the from:

  defp search(query, name) do
    query
    |> where([t], ilike(t.name, ^"%#{name}%"))
  end
2 Likes

here, you will get Item as _query, you can replace
from(query in Item) with (from i in query) and you can add where with a comma so the result would be

defp search(query, name) do
    from i in query, where: ilike(i.name, ^"%#{name}%")
end 

Note that this two query are not the same thing. the second query scope is just inside the from expression and it allows you to do things like.

from(s in schema, where: s.id == 10)

I am sorry to ask but where does the t come from in your code @benwilson512?

Any explanation will be appreciated.

Thanks

t is not a real variable, because where is not a function, it’s a macro. t is part of the syntax of the macro. Examples here: https://hexdocs.pm/ecto/Ecto.Query.html#where/3-expressions-example

The where macro basically just creates a t that you can use in the second part of where.

4 Likes

So it knows when it gets in the pipe that t refers to Item automatically?

Yes. If you pipe a query struct into where, it grabs the schema you’re querying out of the query and makes it available as whatever variable you put in the list.

3 Likes

Thanks a lot know I understand why it can be written like this.

1 Like
defp search(_query, name) do
    query = from(query in Item)

    query
    |> where([t], ilike(t.name, ^"%#{name}%"))
  end

this is the same as you’re writing

defp search(_query, name) do
    Item
    |> where([t], ilike(t.name, ^"%#{name}%"))
  end

that’s why you’re escaping the query parameter to avoid the warning

Yes but now i can use the method mentioned by @benwilson512 and don’t need to ignore query anymore.

1 Like

Final version using the advice from @benwilson512

def list_items(%{matching: name}) when is_binary(name) do
    Item
    # |> where([m], ilike(m.name, ^"%#{name}%"))
    |> search(name)
    |> Repo.all()
  end

  defp search(query, name) do
    query
    |> where([t], ilike(t.name, ^"%#{name}%"))
  end
3 Likes