Compile Error - User.__struct__/1 is undefined, cannot expand struct User

Viewed 2451

I'm building a simple app following the Programming Phoenix 1.4 book.

While adding logic to create a new User, I'm getting this error:

== Compilation error in file lib/rumbl_web/controllers/user_controller.ex ==
** (CompileError) lib/rumbl_web/controllers/user_controller.ex:19: Rubml.Accounts.User.__struct__/1 is undefined, cannot expand struct Rubml.Accounts.User. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code
    (stdlib 3.12.1) lists.erl:1354: :lists.mapfoldl/3
    lib/rumbl_web/controllers/user_controller.ex:18: (module)
    (stdlib 3.12.1) erl_eval.erl:680: :erl_eval.do_apply/6

I've double checked and don't think I've missed anything or that I have any typos.

Here is my controller:

defmodule RumblWeb.UserController do
    use RumblWeb, :controller

    alias Rumbl.Accounts
    alias Rubml.Accounts.User

    def index(conn, _params) do
        users = Accounts.list_users()
        # IO.puts users
        render(conn, "index.html", users: users)
    end

    def show(conn, %{"id" => id}) do
        user = Accounts.get_user(id)
        render(conn, "show.html", user: user)
    end

    def new(conn, _params) do
        changeset = Accounts.change_user(%User{})
        render(conn, "new.html", changeset: changeset)
    end
end

And the User model:


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

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

        timestamps()
    end

    def changeset(user, attrs) do
        user
        |> cast(attrs, [:name, :username])
        |> validate_required([:name, :username])
        |> validate_length(:username, min: 1, max: 20)
    end
end

Here is the repo link if anyone wants to explore: https://github.com/niranjans/rumbl

2 Answers

You have a typo in alias Rubml.Accounts.User -- Rubml should be Rumbl. (I think I made that same mistake when I worked through that book).

The takeaway should be that when a module is not found:

  1. Triple-check the spelling/capitalization of the module name using a case-sensitive search.
  2. Choose a naming convention that is alias-friendly -- keep an eye out for aliases whose segments are named the same as modules.

I had the file under the wrong path: rumbl/accounts/user.ex instead of rumbl/lib/rumbl/accounts/user.ex

Then exit and re-enter iex -S mix

(and I'm running mix phx.server in the background but idk if it makes a difference)

Related