Elixir 如何组合变更集错误?

Elixir 如何组合变更集错误?,elixir,phoenix-framework,Elixir,Phoenix Framework,我正在尝试合并变更集错误 我有一个属于用户模式的机构模式。每个字段上都需要一些字段,但错误响应如下所示: { "errors": { "user": { "password_confirmation": [ "The password confirmation does not match the password." ], "password": [

我正在尝试合并变更集错误

我有一个属于用户模式的机构模式。每个字段上都需要一些字段,但错误响应如下所示:

{
    "errors": {
        "user": {
            "password_confirmation": [
                "The password confirmation does not match the password."
            ],
            "password": [
                "This field is required."
            ],
            "name": [
                "This field is required."
            ]
        },
        "institution": {
            "web_address": [
                "is required."
            ]
        },

    }
}
 user_changeset =
      User.normal_user_changeset(%User{}, %{
        :email => Map.get(attrs, "email"),
        :password => Map.get(attrs, "password"),
        :password_confirmation => Map.get(attrs, "password_confirmation"),
        :name => Map.get(attrs, "name"),
        :postcode => Map.get(attrs, "postcode"),
        :dob => Map.get(attrs, "dob")
      })

    institution =
      %Institution{}
      |> Institution.changeset(%{
        :web_address => Map.get(attrs, "web_address"),
        :person_responsible => Map.get(attrs, "person_responsible"),
        :annual_turnover => Map.get(attrs, "annual_turnover")
      })
      |> Ecto.Changeset.put_assoc(:user, user_changeset)
      |> Repo.insert()
如何将这些错误对象合并为一个

我的插入看起来像:

{
    "errors": {
        "user": {
            "password_confirmation": [
                "The password confirmation does not match the password."
            ],
            "password": [
                "This field is required."
            ],
            "name": [
                "This field is required."
            ]
        },
        "institution": {
            "web_address": [
                "is required."
            ]
        },

    }
}
 user_changeset =
      User.normal_user_changeset(%User{}, %{
        :email => Map.get(attrs, "email"),
        :password => Map.get(attrs, "password"),
        :password_confirmation => Map.get(attrs, "password_confirmation"),
        :name => Map.get(attrs, "name"),
        :postcode => Map.get(attrs, "postcode"),
        :dob => Map.get(attrs, "dob")
      })

    institution =
      %Institution{}
      |> Institution.changeset(%{
        :web_address => Map.get(attrs, "web_address"),
        :person_responsible => Map.get(attrs, "person_responsible"),
        :annual_turnover => Map.get(attrs, "annual_turnover")
      })
      |> Ecto.Changeset.put_assoc(:user, user_changeset)
      |> Repo.insert()
我希望错误响应为:

 {
        "errors": {
                "password_confirmation": [
                    "The password confirmation does not match the password."
                ],
                "password": [
                    "This field is required."
                ],
                "name": [
                    "This field is required."
                ]
                "web_address": [
                    "is required."
                ]
        }
    }
我的回退控制器中有此功能(默认情况下):


errors
只是
%exto.Changeset{}
结构中的值之一

也就是说,人们总是可以修改
%exto.Changeset{}
来提供自定义
错误

def fix_errors(%exto.Changeset{errors:errors}=ch)do
%转换集{ch| errors:errors++[:my_custom_error]}
结束
您需要的只是使用上述函数重新映射输入,并将结果嵌入变更集链中:

机构=
%机构{}
|> ...
|>外部变更集放置关联(:用户,用户变更集)
|>修复错误()
|>回购协议插入()

无论您是否为
错误前后提供了有效的长生不老药术语,我都可以演示如何执行转换本身。例如:

错误=%{
机构:%{web_地址:[“是必需的”]},
用户:%{
名称:[“是必需的。”],
密码:[“是必需的。”],
密码确认:[“不匹配”]
}
}
可能会扁平化为:

输入
|>映射(fn{,v}->v end)
|>枚举减少(&Map.merge/2)
#⇒ %{
#名称:[“是必需的。”],
#密码:[“是必需的。”],
#密码确认:[“不匹配”],
#网址:[“是必需的”]
# }

您可以获取
错误
字段的值,并使用
Enum.reduce/3将它们全部合并:

map = Jason.decode! """
{
    "errors": {
        "user": {
            "password_confirmation": [
                "The password confirmation does not match the password."
            ],
            "password": [
                "This field is required."
            ],
            "name": [
                "This field is required."
            ]
        },
        "institution": {
            "web_address": [
                "is required."
            ]
        }
    }
}
"""

Map.update!(map, "errors", fn errors ->
  errors |> Map.values() |> Enum.reduce(%{}, &Map.merge/2)
end)
|> IO.inspect
输出:

%{
  "errors" => %{
    "name" => ["This field is required."],
    "password" => ["This field is required."],
    "password_confirmation" => ["The password confirmation does not match the password."],
    "web_address" => ["is required."]
  }
}

请澄清您想要得到什么(结果示例会很好。)这里的“合并”是什么意思?显示的错误输出需要什么输出?编辑问题FYI:您不需要手动获取
attrs
映射中字符串键的值。您可以将其直接传递给cast,并且
exto
将为您处理它:
User.normal\u User\u变更集(%User{},attrs)