Convention for null Ecto queries

Is there a convention for the case where you want to ensure that a given Ecto query always returns no results, but still supports piping?

For example, in Ruby land ActiveRecord provides the none method that returns a null query object.

Naively I can just use a limit with something like…

defp none(query) do
  from query, limit: 0
end

Is there a more idiomatic route or a way to return some sort of null query object that Repo.all then knows not to even run the query?

I thought perhaps returning nil or [] might serve that purpose, but those are not implemented by Ecto.Query. Probably better that they don’t.

This is handy in cases where I’m filtering a collection of records based upon a user’s permissions prior to piping to other filters.

defp scope(query, user) do
  cond do
    user.role == "admin" -> query
    user.role == "manager" -> from r in query, where: r.user_id == ^user.id
    true -> none(query)
  end
end
2 Likes

Interesting. I don’t know of a way to do that off-hand. But:

from query, where: 1 == 2

would keep the db from hitting tables I’d think. The planner should “know” that matches 0 rows. It’d still do the network op though.

4 Likes

Yup, that’s basically what I used (I used: where: false)

8 Likes

Thanks. I like the simplicity and explicitness of where: false.