Ecto query with dynamic "where nil"

I have a test helper for asserting database values:

def assert_database_has(model, where, prefix \\ nil) do
  query = from(m in model, select: fragment("count(*)"), where: ^where)

  assert 0 < query |> Repo.one(prefix: prefix)
end

but I cannot make it work with this code for example:

assert_database_has(SomeChangeset,
  id: changeset.id,
  some_value: nil
)

I know I need to use is_nil(some_value), but how do I pass it as an argument to the function?

Alternatively, are there any dependencies for database assertions?

query = Enum.reduce(where, Model, fn
  {k, nil}, query -> from m in query, where: is_nil(field(m, ^k))
  {k, v}, query -> from m in query, where: field(m, ^k) == ^v
end)

Notably you could also use `Repo.aggregate(query, :count, :id, prefix: prefix)` instead of the count fragment.
5 Likes