Search code examples
elixirphoenix-framework

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


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


Solution

  • 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.
    3. Make sure your modules are inside the lib/ directory -- by default, only certain directories are compiled, so make sure your file is in the proper place