Trying to fetch a record, ordered by the maximum value of a modules property

My module looks like this:

defmodule Realtime.ListItem do
use Ecto.Schema
import Ecto
import Ecto.Changeset
import Ecto.Query, only: [from: 1, from: 2]
import Ecto.Query, only: [where: 2]

alias Realtime.Repo
alias Realtime.{Board, Card, List, ListItem}

schema “list_items” do
#…
field :sort_order, :integer

timestamps()

end

I am trying to create a simple function that will return the largest value of the property ‘sort_order’.

   def find_max_sort_order(id) do
     query = from(q in ListItem, where: q.id == ^id, order_by: [desc: q.sort_order], limit: 1)
     Repo.all(query)
  end

I am getting this error when trying to start phoenix up:

Compiling 4 files (.ex)
warning: variable “q” does not exist and is being expanded to “q()”, please use parentheses to remove the ambiguity or change the variable name
lib/realtime/models/list_item.ex:32

What am I doing wrong? Am I missing an import?

I simply want to return a single record, which has the maximum value of sort_order.

IMO you are doing too much imports. Only do import Ecto.Query (with or without the only clause) and alias everything else. Then try again.

5 Likes

This worked. So the issue was I was cherry picking and didn’t have the correct imports explicitly?

1 Like

Not exactly. Issue is you are importing too much. Importing Ecto.Query makes sense because prepending it to every usage is pretty annoying. Imagine this:

Ecto.Query.from(x in Company, where: inserted_at >= ~N[2019-06-01 00:00:00.000000])
|> Ecto.Query.preload(:departments)
|> Ecto.Query.order_by(updated_at: :desc)

It gets tedious quickly. So importing Ecto.Query is natural.

Importing everything else however is asking for trouble. Import only the bare minimum because that means that modules might have duplicated function names and the compiler will yell at you.

5 Likes