0
votes

I have what I believe to be a relatively simple Ecto query in Elixir and it is throwing an error "protocol not implemented for" and I am very confused as to why.

So here is the query:

    head_children_list =    Comments
                                |> where([c], c.inserted_at in ^head_children) 
                                |> Enum.sort_by(& &1["votetotal"])

So head_children is a list with one string timestamp value in it. This is the confirmed terminal output:

value of head_children
["2018-10-11 14:08:15.021033"]

So I know for a fact that this is a list. However when I try and perform the above query I get the following:

[info] Sent 500 in 168ms
[error] #PID<0.401.0> running AlbatrossWeb.Endpoint (cowboy_protocol) terminated
Server: localhost:4000 (http)
Request: POST /voteComment
** (exit) an exception was raised:
    ** (Protocol.UndefinedError) protocol Enumerable not implemented for #Ecto.Query<from c in Albatross.Comments, where: c.inserted_at in ^[["2018-10-11 14:08:15.021033"]]>. This protocol is implemented for: DBConnection.PrepareStream, DBConnection.Stream, Date.Range, Ecto.Adapters.SQL.Stream, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, List, Map, MapSet, Postgrex.Stream, Range, Stream

Notice that this says protocol is implemented for lists. But this is a list! So I am very confused. I have tried using ^[head_children], which just wraps it in another list, but this also fails with the same error.

Does anyone know what is going on?

1
Sidenote: it’s always better to sort inside the database.Aleksei Matiushkin

1 Answers

3
votes

where(Comments, [c], c.inserted_at in ^head_children) returns an %Ecto.Query{}, which is piped into Enum.sort_by/2. %Ecto.Query{} is a struct not a list, which is not Enumerable.

You probably want

head_children_list =
  Comments
  |> where([c], c.inserted_at in ^head_children)
  |> Repo.all()
  |> Enum.sort_by(& &1["votetotal"])