如何验证地图字段在Ecto模型中是否具有某个键(而不是在控制器中)?

时间:2018-04-01 20:00:56

标签: database elixir phoenix-framework

我需要将地图作为字段存储到我的数据库中(数据源是JSON)。为了使数据有效,JSON需要有一个密钥,即密钥也必须存在于转换后的Elixir映射中。

在模型模块中执行此验证应该是理想的,而不是手动检查控制器中的密钥,然后使用add_error添加错误。但是,我已经查看了Ecto文档,但到目前为止,验证似乎都是关于非map类型的简单字段,例如:检查string字段是否与某个正则表达式匹配。我似乎无法找到一种简单的方法来做到这一点。我做错了吗?

1 个答案:

答案 0 :(得分:2)

您可以编写自己的验证功能,例如https://stackoverflow.com/a/35331889/2064880https://medium.com/@QuantLayer/writing-custom-validations-for-ecto-changesets-4971881c7684

因此,对于您的用例,这样的事情可能会起作用:

def changeset(struct, params \\ %{}) do
  struct
  |> cast(attrs, [:map_field])
  |> validate_key_exists()
end

defp validate_key_exists(%Ecto.Changeset{changes:
      %{map_field: %{the_special_key: _value}}} = changeset) do
  changeset
end
defp validate_key_exists(changeset) do
  add_error(changeset, :map_field, "Missing special key.")
end