Can't create new entry in database

Hi, just set up a new project and am getting this error:

iex(1)> alias BookList.User
iex(2)> params = %{"username": "jxxcarlson", "email": "jxxcarlson@gmail.com"}
%{email: "jxxcarlson@gmail.com", username: "jxxcarlson"}
iex(3)> ucs = User.changeset(%User{}, params)
** (CompileError) iex:5: BookList.User.__struct__/1 is undefined, cannot expand struct BookList.User
    (stdlib) lists.erl:1354: :lists.mapfoldl/3

In user.ex I have

defmodule BookList.User do
  use BookList.Web, :model

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

    timestamps()
  end

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:username, :email])
    |> validate_required([:username, :email])
  end
end

My guess is the issue is with how you started IEx. By default it doesn’t load any of your code or start any of your processes. You probably just need to do this in the root of your project.

iex -S mix

Hmm… below is what I am doing. I think that I am in the root of the server, no??

 $ pwd
/Users/carlson/dev/apps/bookListProject/book_list
 $ ls
README.md	config		lib		mix.lock	test
_build		deps		mix.exs		priv		web
 $ iex -S mix phx.server
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

[info] Running BookListWeb.Endpoint with Cowboy using http://0.0.0.0:4000
Interactive Elixir (1.6.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> alias BookList.User; params = %{"username": "jxxcarlson", "email": "jxxcarlson@gmail.com"}; ucs = User.changeset(%User{}, params)
** (CompileError) iex:1: BookList.User.__struct__/1 is undefined, cannot expand struct BookList.User
    (stdlib) lists.erl:1354: :lists.mapfoldl/3

That seems like it should work. What happens if you do BookList.User.__info__(:functions)?

Weird – here is what I get:

iex(2)> BookList.User.__info__(:functions)
** (UndefinedFunctionError) function BookList.User.__info__/1 is undefined (module BookList.User is not available)
    BookList.User.__info__(:functions)

Given you have lib and web suggests that you created the project with mix phoenix.new. mix phx.new would have created lib/book_list and lib/book_list_web.

Therefore you should be using iex -S mix phoenix.server.

Perhaps try requiring it first. require BookList.User

I used mix phx.new --no-brunch --no-html book_list and have lib/book_list and lib/book_list_web. See session below. Can’t figure out what is wrong.

$ iex -S mix phoenix.server
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

mix phoenix.server is deprecated. Use phx.server instead.
[info] Running BookListWeb.Endpoint with Cowboy using http://0.0.0.0:4000
Interactive Elixir (1.6.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> BookList.User.__info__(:functions)
** (UndefinedFunctionError) function BookList.User.__info__/1 is undefined (module BookList.User is not available)
    BookList.User.__info__(:functions)

iex(1)> require BookList.Use
** (CompileError) iex:1: module BookList.Use is not loaded and could not be found

You forgot the r in BookList.User

Where is that user.ex? (phx.new wouldn’t create that web directory.)

In a “healthy project”:

iex(2)> Rumbl.Accounts.User.__info__(:functions)
[
  __changeset__: 0,
  __schema__: 1,
  __schema__: 2,
  __struct__: 0,
  __struct__: 1,
  changeset: 2,
  registration_changeset: 2
]

for rumbl/lib/rumbl/accounts/user.ex

Assuming you’re using Phoenix 1.3, try replacing use BookList.Web, :model with use Ecto.Schema and import Ecto.Changeset. But I agree with @peerreynders, the existence of separate web and lib directories suggests that something’s not kosher. Are you sure you’re using 1.3?

1 Like

Sorry, typo, but the result is the same:

iex(2)> require BookList.User
** (CompileError) iex:2: module BookList.User is not loaded and could not be found

How do I check the Phoenix version?

The project version is listed in mix.exs:

  defp deps do
    [
      {:phoenix, "~> 1.3.2"},
      {:phoenix_pubsub, "~> 1.0"},
      {:phoenix_ecto, "~> 3.2"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_html, "~> 2.10"},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:gettext, "~> 0.11"},
      {:cowboy, "~> 1.0"},
      {:comeonin, "~> 4.1"},
      {:bcrypt_elixir, "~> 1.0"}
    ]
  end

For the installed version:

$ mix phx.new --version
Phoenix v1.3.2

You can check the version of the phoenix mix archive by running mix phx.new -v.

This is what I have:’

 $ mix phx.new --version
Phoenix v1.3.2

Maybe I should start over. I was just setting up this project, so no harm would be done. Does seem fishy.

A 1.3 project created with phoenix.new would create book_list/web/web.ex which contains:

defmodule BookList.Web do
  # ...

  def model do
    quote do
      # Define common model functionality
    end
  end

A 1.3 project created with phx.new would create book_list/lib/book_list_web.ex which contains:

defmodule BookListWeb do
  # ...

without any model definition.

So use BookList.Web, :model couldn’t work in a phx.new project.

1 Like

You might want to try out the Phoenix generators to get a feel for how things go together. https://hexdocs.pm/phoenix/Mix.Tasks.Phoenix.Gen.Html.html#content

Or

https://hexdocs.pm/phoenix/Mix.Tasks.Phoenix.Gen.Model.html#content

Those links discuss the old style generators (phoenix.gen) which are only relevant for existing applications. For new applications only the new style generators (phx.gen) should be used.

Like: https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Json.html#content

1 Like

My previous troubles arose from mixing phoenix and phx – I had been using generators, as in the session below. So here is a new try with

  660  mix phx.new --no-brunch --no-html book_list
  661  cd book_list/
  662  atom .
  663  mix phx.gen.json BookSpace User users username:string email:string
  664  mix ecto.migrate

T’his gives the error

$ mix ecto.migrate
Compiling 16 files (.ex)

== Compilation error in file lib/book_list_web/controllers/user_controller.ex ==
** (CompileError) lib/book_list_web/controllers/user_controller.ex:18: undefined function user_path/3
    (stdlib) lists.erl:1338: :lists.foreach/2
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (elixir) lib/kernel/parallel_compiler.ex:198: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6