Ecto changeset添加多个错误

时间:2017-03-28 16:00:27

标签: elixir phoenix-framework ecto

我有一个配置图,我想在变更集中验证。配置有多个密钥,每个密钥都有一些约束。

我可以在收到数据时为每个人运行一个验证器但是这迫使我编写了很多代码,这些代码可以更聪明地完成,因此我运行循环并尝试收集所有失败的验证而不是运行他们一个接一个。

defp validate_config_flags(changeset) do
    config = get_field(changeset, :config)

    for  {k, v} <- config  do
        if !Map.has_key?(@config_flags, k) || !validate_config_flag(k, v) do
            add_error(changeset, :"#{k}", "Invalid value for `#{k}`")
        end
    end

    changeset
end

我的问题是,即使某些字段失败并且我的问题与此相关,我也会返回changeset。如何向结果添加多个错误消息/失败验证,而不是以某种方式在第一个add_error返回?

1 个答案:

答案 0 :(得分:3)

大多数情况下,当你想在Elixir中反复修改一个词时,你正在寻找Enum.reduce/3

defp validate_config_flags(changeset) do
  Enum.reduce(get_field(changeset, :config), changeset, fn {k, v}, changeset ->
    if !Map.has_key?(@config_flags, k) || !validate_config_flag(k, v) do
      add_error(changeset, :"#{k}", "Invalid value for `#{k}`")
    else
      changeset
    end
  end)
end

此代码与您的代码相同,但它会跟踪changeset在每一步返回的新add_error,类似于以下如果 Elixir具有可变变量:< / p>

for {k, v} <- config  do
  if !Map.has_key?(@config_flags, k) || !validate_config_flag(k, v) do
    changeset = add_error(changeset, :"#{k}", "Invalid value for `#{k}`")
  end
end