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?