I'm new to Elixir, Phoenix and Ecto so I'm following a video tutorial. The tutorial is setting up credentials for users through schemas with each user having one unique credential. So I have a user:
defmodule Foo.Accounts.User do
use Ecto.Schema
import Ecto.Changeset
alias Foo.Accounts.Credential
schema "users" do
field :name, :string
field :username, :string
has_one :credential, Credential
timestamps()
end
@doc false
def changeset(user, attrs) do
user
|> cast(attrs, [:name, :username])
|> validate_required([:name, :username])
|> unique_constraint(:username)
end
end
and a credential:
defmodule Foo.Accounts.Credential do
use Ecto.Schema
import Ecto.Changeset
alias Foo.Accounts.User
schema "credentials" do
field :email, :string
belongs_to :user, User
timestamps()
end
def changeset(credential, attrs) do
credential
|> cast(attrs, [:email])
|> validate_required([:email])
|> unique_constraint(:email)
end
end
The create_user code is:
def create_user(attrs \\ %{}) do
%User{}
|> User.changeset(attrs)
|> Ecto.ChangeSet.cast_assoc(:credential, with: &Credential.changeset/2)
|> Repo.insert()
end
The create credential code is
def create_credential(attrs \\ %{}) do
%Credential{}
|> Credential.changeset(attrs)
|> Repo.insert()
end
When I try to insert a user - with full valid data - I get the error
UndefinedFunctionError at POST /users function Ecto.ChangeSet.cast_assoc/3 is undefined (module Ecto.ChangeSet is not available)
and I don't know why.
The error screen shows Ecto.ChangeSet.cast_assoc/3 Called with 3 arguments #Ecto.Changeset<action: nil, changes: %{name: "jimmyjobber", username: "jimmyjobber"}, errors: [], data: #Foo.Accounts.User<>, valid?: true> :credential [with: &Foo.Accounts.Credential.changeset/2]
and
user %{"email" => "[email protected]", "name" => "jimmyjobber", "username" => "jimmyjobber"}
From the Ecto docs cast_assoc/3 is used when working with external data.
An extensive search has found articles close to my problem, but nothing that helped.
Please tell me what I have missed so I can move on with this tutorial.
Ecto.ChangeSet
, the name isEcto.Changeset
, you can notice that by looking at the import in your schema module. – Daniel