问题描述
我是 Elixir、Phoenix 和 Ecto 的新手,所以我正在学习视频教程。本教程通过架构为用户设置凭据,每个用户都有一个唯一的凭据。所以我有一个用户:
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
和证书:
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
create_user 代码是:
def create_user(attrs \\ %{}) do
%User{}
|> User.changeset(attrs)
|> Ecto.ChangeSet.cast_assoc(:credential,with: &Credential.changeset/2)
|> Repo.insert()
end
创建凭据代码为
def create_credential(attrs \\ %{}) do
%Credential{}
|> Credential.changeset(attrs)
|> Repo.insert()
end
POST /users 时出现 UndefinedFunctionError 函数 Ecto.ChangeSet.cast_assoc/3 未定义(模块 Ecto.ChangeSet 不可用)
我不知道为什么。
错误屏幕显示
Ecto.ChangeSet.cast_assoc/3
用 3 个参数调用
#Ecto.Changeset
和
用户 %{"email" => "jimmyjobber@emailaddress.com","name" => "jimmyjobber","username" => "jimmyjobber"}
来自 Ecto 文档的 cast_assoc/3 用于处理外部数据。
请告诉我我错过了什么,以便我继续学习本教程。
解决方法
正如之前的评论所指出的,模块的正确名称是 Ecto.Changeset
-- 大小写很重要!尽管 Elixir 已编译,但它仍然具有一些运行时灵活性,允许使用动态模块名称之类的东西:在其他语言中,拼写错误的模块名称将是 编译时 错误,但在 Elixir 中,这些是运行时错误 (!)。 (这是设计使然:这是使 Erlang/Elixir 可热插拔并能够更新正在运行的系统的部分原因。
这里的要点是非常注意模块和函数名称的大小写。任何时候遇到“未定义”错误时,请三重检查模块名称拼写是否正确。