Phoenix 1.3.0 released

All seems correct. I checked migration credential too, but same error.

What @chrismccord wanted to know is, if you have a line like this in your module:

alias FooBar.Credentials

If it is there, please show more of your code.

1 Like

As @chrismccord and @NobbZ wrote, there is no such module as Credentials in your code, so you have to use alias for proper module, namely Ins.Accounts.Credentials as we can see in the screenshot.

1 Like

here are my files:
Credential.ex

defmodule Ins.Accounts.Credential do
  use Ecto.Schema
  import Ecto.Changeset
  alias Ins.Accounts.{Credential, User}


  schema "credentials" do
    field :email, :string
    belongs_to :user, User

    timestamps()
  end

  @doc false
  def changeset(%Credential{} = credential, attrs) do
    credential
    |> cast(attrs, [:email])
    |> validate_required([:email])
    |> unique_constraint(:email)
  end
end

User.ex

defmodule Ins.Accounts.User do
  use Ecto.Schema
  import Ecto.Changeset
  alias Ins.Accounts.{User, Credential}


  schema "users" do
    field :name, :string
    field :username, :string
    has_one :credential, Credential

    timestamps()
  end

  @doc false
  def changeset(%User{} = user, attrs) do
    user
    |> cast(attrs, [:name, :username])
    |> validate_required([:name, :username])
    |> unique_constraint(:username)
  end
end

Account.ex

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

  import Ecto.Query, warn: false
  alias Ins.Repo

  alias Ins.Accounts.User

  @doc """
  Returns the list of users.

  ## Examples

      iex> list_users()
      [%User{}, ...]

  """
  def list_users do
    User
    |> Repo.all()
    |> Repo.preload(:credential)
  end
  ...
end

So in your InsWeb.Controllers.UserController (I’m guessing it is) at the top of your module definition you need to add something like alias Ins.Accounts.Credentials to bring Credentials into active scope. :slight_smile:

I tried it …before I posted this troubleshoot…I doesn’t work.

We still have not seen your InsWeb.Controllers.UserController code, because it absolutely should work. ^.^

my generated user_controller.ex looks like that:

defmodule InsWeb.UserController do
  use InsWeb, :controller

  alias Ins.Accounts
  alias Ins.Accounts.User
  ## alias Ins.Accounts.Credential

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

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

  def create(conn, %{"user" => user_params}) do
    case Accounts.create_user(user_params) do
      {:ok, user} ->
        conn
        |> put_flash(:info, "User created successfully.")
        |> redirect(to: user_path(conn, :show, user))
      {:error, %Ecto.Changeset{} = changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end

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

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

  def update(conn, %{"id" => id, "user" => user_params}) do
    user = Accounts.get_user!(id)

    case Accounts.update_user(user, user_params) do
      {:ok, user} ->
        conn
        |> put_flash(:info, "User updated successfully.")
        |> redirect(to: user_path(conn, :show, user))
      {:error, %Ecto.Changeset{} = changeset} ->
        render(conn, "edit.html", user: user, changeset: changeset)
    end
  end

  def delete(conn, %{"id" => id}) do
    user = Accounts.get_user!(id)
    {:ok, _user} = Accounts.delete_user(user)

    conn
    |> put_flash(:info, "User deleted successfully.")
    |> redirect(to: user_path(conn, :index))
  end
end

You have commented the alias line. Remove the # in front of it.

That actually will not work in this case. :slight_smile:

Seeing this file is definitely what I needed. I’m guessing, based on counting, that this line is line 45:

    case Accounts.update_user(user, user_params) do

And if so it is failing inside that, so next we need to see your INS.Account module, I bet it is that module that needs the alias (wherever the Credentials.changeset call actually exists is the same module where the alias needs to exist). :slight_smile:

@OvermindDL1 my account module is up. I thought also that I’d add this alias in my Account module but it shown the same result.

Here is the whole content:

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

  import Ecto.Query, warn: false
  alias Ins.Repo

  alias Ins.Accounts.User
#   alias Ins.Accounts.Credential

  @doc """
  Returns the list of users.

  ## Examples

      iex> list_users()
      [%User{}, ...]

  """
  def list_users do
    User
    |> Repo.all()
    |> Repo.preload(:credential)
  end

  @doc """
  Gets a single user.

  Raises `Ecto.NoResultsError` if the User does not exist.

  ## Examples

      iex> get_user!(123)
      %User{}

      iex> get_user!(456)
      ** (Ecto.NoResultsError)

  """
#   def get_user!(id), do: Repo.get!(User, id)
  def get_user!(id) do
    User
    |> Repo.get!(id)
    |> Repo.preload(:credential)
  end

  @doc """
  Creates a user.

  ## Examples

      iex> create_user(%{field: value})
      {:ok, %User{}}

      iex> create_user(%{field: bad_value})
      {:error, %Ecto.Changeset{}}

  """
  def create_user(attrs \\ %{}) do
    %User{}
    |> User.changeset(attrs)
    |> Ecto.Changeset.cast_assoc(:credential, with: &Credential.changeset/2)
    |> Repo.insert()
  end

  @doc """
  Updates a user.

  ## Examples

      iex> update_user(user, %{field: new_value})
      {:ok, %User{}}

      iex> update_user(user, %{field: bad_value})
      {:error, %Ecto.Changeset{}}

  """
  def update_user(%User{} = user, attrs) do
    user
    |> User.changeset(attrs)
    |> Ecto.Changeset.cast_assoc(:credential, with: &Credential.changeset/2)
    |> Repo.update()
  end

  @doc """
  Deletes a User.

  ## Examples

      iex> delete_user(user)
      {:ok, %User{}}

      iex> delete_user(user)
      {:error, %Ecto.Changeset{}}

  """
  def delete_user(%User{} = user) do
    Repo.delete(user)
  end

  @doc """
  Returns an `%Ecto.Changeset{}` for tracking user changes.

  ## Examples

      iex> change_user(user)
      %Ecto.Changeset{source: %User{}}

  """
  def change_user(%User{} = user) do
    User.changeset(user, %{})
  end

  alias Ins.Accounts.Credential

  @doc """
  Returns the list of credentials.

  ## Examples

      iex> list_credentials()
      [%Credential{}, ...]

  """
  def list_credentials do
    Repo.all(Credential)
  end

  @doc """
  Gets a single credential.

  Raises `Ecto.NoResultsError` if the Credential does not exist.

  ## Examples

      iex> get_credential!(123)
      %Credential{}

      iex> get_credential!(456)
      ** (Ecto.NoResultsError)

  """
  def get_credential!(id), do: Repo.get!(Credential, id)

  @doc """
  Creates a credential.

  ## Examples

      iex> create_credential(%{field: value})
      {:ok, %Credential{}}

      iex> create_credential(%{field: bad_value})
      {:error, %Ecto.Changeset{}}

  """
  def create_credential(attrs \\ %{}) do
    %Credential{}
    |> Credential.changeset(attrs)
    |> Repo.insert()
  end

  @doc """
  Updates a credential.

  ## Examples

      iex> update_credential(credential, %{field: new_value})
      {:ok, %Credential{}}

      iex> update_credential(credential, %{field: bad_value})
      {:error, %Ecto.Changeset{}}

  """
  def update_credential(%Credential{} = credential, attrs) do
    credential
    |> Credential.changeset(attrs)
    |> Repo.update()
  end

  @doc """
  Deletes a Credential.

  ## Examples

      iex> delete_credential(credential)
      {:ok, %Credential{}}

      iex> delete_credential(credential)
      {:error, %Ecto.Changeset{}}

  """
  def delete_credential(%Credential{} = credential) do
    Repo.delete(credential)
  end

  @doc """
  Returns an `%Ecto.Changeset{}` for tracking credential changes.

  ## Examples

      iex> change_credential(credential)
      %Ecto.Changeset{source: %Credential{}}

  """
  def change_credential(%Credential{} = credential) do
    Credential.changeset(credential, %{})
  end
end

Awesome, that is what I needed, your earlier post cut it off before it showed the error line. ^.^;

So the error line is:

    |> Ecto.Changeset.cast_assoc(:credential, with: &Credential.changeset/2)

So yeah, the alias line you have commented out really should be all that is required. Actually I’m not sure how that module is even compiling without it since you struct-create the Credential in that file too. o.O?

No…I commented it because in my own opinion i thought I had to put it at the top level (with no success it showed the same error) otherwise the alias Ins.Accounts.Credential was already inserted…with the generator…! line 114

Yeah the generator only puts it at the top of the area where the generator generates code that uses it. If you adjust code ā€˜higher’ than the alias to use the code then the alias needs to be moved up too.

2 Likes

@chrismccord @OvermindDL1 @all …
My bad, when I added this alias Ins.Accounts.Credential at the top level after alias Ins.Accounts.User I forgot to delete the one I left at line 114 so the code was corrupted. Now it works.
Thank you!!!

2 Likes

Is there a newer version or is the the final one?

Thank you!
Does it contain an installation guide too?