Repo.count in Ecto

Sep 20, 2016
ecto, elixir, tip
Enable Repo.count(query) in Ecto

I have often wanted to just do the following but Ecto’s Repo module doesn’t have a count method.

1
2
iex> MyApp.Repo.count(MyApp.Account)
42

It is not too difficult to create a count function that will allow you to count the results of any query.

1
2
3
4
5
6
7
8
9
10
11
defmodule MyApp.DBUtils do
  import Ecto.Query, only: [from: 2]

  @doc "Generate a select count(id) on any query"
  def count(query),
    do: from t in clean_query_for_count(query), select: count(t.id)

  # Remove the select field from the query if it exists
  defp clean_query_for_count(query),
    do: Ecto.Query.exclude(query, :select)
end

This will provide a shortcut for counting any query

1
MyApp.DBUtils.count(MyApp.Account) |> Repo.one!

Now, to enable Repo.count we can modify the repo module usually found in lib/my_app/repo.ex

1
2
3
4
5
6
defmodule MyApp.Repo do
  use Ecto.Repo, otp_app: :my_app

  def count(query),
    do: MyApp.DBUtils.count(query) |> __MODULE__.one!
end

That’s it. This will enable a count on any query including complicated queries and those that have a select expression set.

comments powered by Disqus