如何验证嵌套地图中的要求
How to validate required in nested map
我正在使用 Elixir。
我收到了一些属性,我正在使用它们创建一个 location
。属性类似于:
attrs = %{latitude: 123.2, longitude: 123.4, metadata: %{timestamp: "2015-05-05T01:31:54", accuracy: 1}}
创建我使用:
location
|> cast(attrs, [:latitude, :longitude, :metadata])
|> validate_required([:latitude, :longitude])
有什么方法可以验证 metadata.timestamp 的要求吗?
谢谢!
您可以为您的元数据创建另一个架构,然后嵌入一个 Metadata
。这将使您能够投射和验证元数据中的字段。代码如下所示:
defmodule Location do
use Ecto.Schema
schema "location" do
field :latitude, :float
field :longitude, :float
embeds_one :metadata, Metadata
end
def changeset(location, attrs) do
location
|> cast(attrs, [:latitude, :longitude, :metadata])
|> validate_required([:latitude, :longitude])
|> cast_embed(:metadata)
end
end
和您的元数据:
defmodule Metadata do
use Ecto.Schema
embedded_schema do
field :timestamp, :utc_datetime
field :accuracy, :integer
end
def changeset(metadata, attrs) do
location
|> cast(attrs, [:timestamp, :accuracy])
|> validate_required([:timestamp])
end
end
这将是使用 Ecto Schemas 进行结构验证嵌套映射的方法,但是 ofc。您可以编写自己的验证函数,here 是一个关于如何做到这一点的示例。
使用 Harun 回答的部分内容和来自不同论坛的另一个回答,我解决了这个问题:
defp validate_metadata_contains_timestamp(changeset, field) do
validate_change(changeset, field, fn (current_field, value) ->
case Map.fetch(value, "timestamp") do
{:ok, _} -> []
:error -> [{current_field, "The field metadata must have a timestamp"}]
end
end)
end
我正在使用 Elixir。
我收到了一些属性,我正在使用它们创建一个 location
。属性类似于:
attrs = %{latitude: 123.2, longitude: 123.4, metadata: %{timestamp: "2015-05-05T01:31:54", accuracy: 1}}
创建我使用:
location
|> cast(attrs, [:latitude, :longitude, :metadata])
|> validate_required([:latitude, :longitude])
有什么方法可以验证 metadata.timestamp 的要求吗? 谢谢!
您可以为您的元数据创建另一个架构,然后嵌入一个 Metadata
。这将使您能够投射和验证元数据中的字段。代码如下所示:
defmodule Location do
use Ecto.Schema
schema "location" do
field :latitude, :float
field :longitude, :float
embeds_one :metadata, Metadata
end
def changeset(location, attrs) do
location
|> cast(attrs, [:latitude, :longitude, :metadata])
|> validate_required([:latitude, :longitude])
|> cast_embed(:metadata)
end
end
和您的元数据:
defmodule Metadata do
use Ecto.Schema
embedded_schema do
field :timestamp, :utc_datetime
field :accuracy, :integer
end
def changeset(metadata, attrs) do
location
|> cast(attrs, [:timestamp, :accuracy])
|> validate_required([:timestamp])
end
end
这将是使用 Ecto Schemas 进行结构验证嵌套映射的方法,但是 ofc。您可以编写自己的验证函数,here 是一个关于如何做到这一点的示例。
使用 Harun 回答的部分内容和来自不同论坛的另一个回答,我解决了这个问题:
defp validate_metadata_contains_timestamp(changeset, field) do
validate_change(changeset, field, fn (current_field, value) ->
case Map.fetch(value, "timestamp") do
{:ok, _} -> []
:error -> [{current_field, "The field metadata must have a timestamp"}]
end
end)
end