【发布时间】:2016-08-27 19:24:01
【问题描述】:
我正在尝试确定在 Ecto 2 中验证多对多关系的正确方法。我有一个需要有很多成员的对话模型,并且用户可以成为许多对话的一部分,所以我已经像这样建立模型:
# User Model
defmodule MyApp.User do
...
schema "users" do
....
many_to_many :conversations, Conversation, join_through: "conversations_users"
...
end
...
end
# Conversation Model
defmodule MyApp.Conversation do
...
schema "conversations" do
has_many :messages, Message
many_to_many :members, User, join_through: "conversations_users"
timestamps()
end
def changeset(struct, _params) do
struct
|> validate_member_count
end
defp validate_member_count(changeset) do
members = Repo.all(assoc(changeset, :members))
valid? = length(members) == 2
if valid? do
add_error(changeset, :members, "foo")
else
changeset
end
end
end
但是,我无法让它工作。我编写了一个简单的测试来验证验证是否正确运行,但我不断收到以下错误:
# Test
test "fails to validate a conversation with less than two members" do
changeset = Conversation.changeset(%Conversation{}, %{})
{message, []} = changeset.errors[:members]
assert message === "must have at least two members"
end
** (FunctionClauseError) Ecto.Changeset.add_error/4 中没有函数子句匹配
我很难理解我做错了什么。似乎找不到函数,但我检查了文档,似乎Ecto.Changeset.add_error/4 绝对正确,而且它的参数似乎也正确。
我最好的猜测是,在调用我的自定义验证器之前,我需要在验证中做一些事情,但我就是不知道我应该做什么。
【问题讨论】:
-
尝试在
MyApp.Conversation.changeset/2中将struct |> validate_member_count替换为struct |> change |> validate_member_count。 -
我现在得到一个不同的错误:
** (UndefinedFunctionError) function Ecto.Changeset.__schema__/2 is undefined or private -
尝试用
Repo.all(assoc(changeset.data, :members))替换Repo.all(assoc(changeset, :members))。 -
是的!做到了!非常感谢。请提交正确的答案,以便我接受!
标签: validation associations elixir ecto