Ecto error while following book

I am trying to follow along with the Programming Phoenix 1.4 book and I ran into an error right before the building forms section.

The error I am getting on the webpage is:

Protocol.UndefinedError at GET /users

protocol Ecto.Queryable not implemented for User, the given module does not exist. This protocol is implemented for: Atom, BitString, Ecto.Query, Ecto.SubQuery, Tuple

This error only came after I changed my account.ex file which the book said to do. It currently looks like this:

  0 defmodule Rumbl.Accounts do
  1   alias Rumbl.Repo
  2
  3   def get_user(id) do
  4   ¦ Repo.get(User, id)
  5   end
  6   def get_user!(id) do
  7   ¦ Repo.get!(User, id)
  8   end
  9   def get_user_by(params) do
 10   ¦ Repo.get_by(User, params)
 11   end
 12   def list_users do
 13   ¦ Repo.all(User)
 14   end
 15 end
1 Like

I expect you’re missing an alias for User. Any ecto schema module automatically implements Ecto.Queryable, but the error is telling you you’re trying to run queries on a module, which doesn’t implement it. It also says User is missing the implementation, while your schema is probably Rumbl.Accounts.User.

4 Likes

I had already added the alias and am still getting the same error. Same if I remove the alias and just use Rumbl.Accounts.User. I have no idea what else the problem is or even how to troubleshoot it as I’m pretty new at Phoenix and even Elixir itself. My Rumbl.Accounts.User module includes use Ecto.Schema and import Ecto.Changeset, as well as defining the schema "users". Any idea what else might be wrong? Thanks so much.

@danascheider can you share your full Rumbl.Accounts, Rumble.Accounts.User modules and a full stacktrace/error message?

Sure @axelson, here’s Rumbl.Accounts.User:

defmodule Rumbl.Accounts.User do
  use Ecto.Schema
  import Ecto.Changeset

  schema "users" do
    field :name, :string
    field :username, :string

    timestamps()
  end
end

And Rumbl.Accounts:

defmodule Rumbl.Accounts do
  @moduledoc """
  The Accounts context.
  """

  alias Rumbl.Accounts.User
  alias Rumbl.Repo

  def get_user(id) do
    Repo.get(User, id)
  end

  def get_user!(id) do
    Repo.get!(User, id)
  end

  def get_user_by(params) do
    Repo.get_by(User, params)
  end

  def list_users do
    Repo.all(User)
  end
end

And the error message is this:

Request: GET /users
** (exit) an exception was raised:
    ** (Protocol.UndefinedError) protocol Ecto.Queryable not implemented for Rumbl.Accounts.User, the given module does not provide a schema. This protocol is implemented for: Atom, BitString, Ecto.Query, Ecto.SubQuery, Tuple
        (ecto) lib/ecto/queryable.ex:40: Ecto.Queryable.Atom.to_query/1
        (ecto) lib/ecto/repo/queryable.ex:14: Ecto.Repo.Queryable.all/3
        lib/rumbl_web/controllers/user_controller.ex:7: RumblWeb.UserController.index/2
        lib/rumbl_web/controllers/user_controller.ex:1: RumblWeb.UserController.action/2
        lib/rumbl_web/controllers/user_controller.ex:1: RumblWeb.UserController.phoenix_controller_pipeline/2
        (rumbl) lib/rumbl_web/endpoint.ex:1: RumblWeb.Endpoint.instrument/4
        (phoenix) lib/phoenix/router.ex:275: Phoenix.Router.__call__/1
        (rumbl) lib/rumbl_web/endpoint.ex:1: RumblWeb.Endpoint.plug_builder_call/2
        (rumbl) lib/plug/debugger.ex:122: RumblWeb.Endpoint."call (overridable 3)"/2
        (rumbl) lib/rumbl_web/endpoint.ex:1: RumblWeb.Endpoint.call/2
        (phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:34: Phoenix.Endpoint.Cowboy2Handler.init/2
        (cowboy) /Users/danascheider/rumbl/deps/cowboy/src/cowboy_handler.erl:41: :cowboy_handler.execute/2
        (cowboy) /Users/danascheider/rumbl/deps/cowboy/src/cowboy_stream_h.erl:296: :cowboy_stream_h.execute/3
        (cowboy) /Users/danascheider/rumbl/deps/cowboy/src/cowboy_stream_h.erl:274: :cowboy_stream_h.request_process/3
        (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

Oh and also - the code works fine in iex.

Let me know if you need any more info. Thanks!

Hmmm, if it’s working in iex than that points to an issue with the controller. What do you have in there currently? From the stacktrace it looks like your index function is directly calling Repo instead of using a function from Rumbl.Accounts. Perhaps you didn’t alias Rumbl.Accounts.User in the controller?

I feel dumb - I just had to run mix do clean, compile and restart my server and now it works. Found somebody at the office who figured it out.

Thanks for your help though!

1 Like