如何添加条件必填字段?
How to add a conditional required field?
我有一个具有此(简化)架构的地址的 ecto 模型:
defmodule Address do
use Ecto.Model
schema "addresses" do
field :zip, :string
field :country, :string
# snip
end
@countries_requiring_zip ~w(US) # snip
def changeset(model, params \ :empty) do
model
|> cast(params, ~w(country), ~w(zip))
|> validate_zip
end
defp validate_zip(changeset) do
if get_field(changeset, :country) in @countries_requiring_zip do
# ????
end
changeset
end
end
我想将 zip
标记为必需而不是可选,但前提是该国家/地区在白名单中,但我想不出一种简洁的方式来编写验证。如何添加该约束?
没有明确的函数要求 cast
之外的字段。您可以使用 validate_length/3 函数并覆盖 ':message' 选项。
validate_length(changeset, :zip, min: 1, message: "is required when country is US")
您也可以简单地定义多个转换:
def changeset(model, params \ :empty) do
model
|> cast(params, ~w(country), ~w())
|> cast_by_country(params)
end
defp cast_by_country(changeset, params) do
case get_field(changeset, :country) do
"US" -> cast(changeset, params, ~w(zip), ~w())
_ -> cast(changeset, params, ~w(), ~w(zip))
end
end
get_field/2
将从更改中读取一个值,如果没有则回退到结构一。这是变更集的最大好处:它只是数据结构,您可以使用常规的 Elixir 代码进行条件检查、验证等。直接编写、阅读和测试。 :)
我有一个具有此(简化)架构的地址的 ecto 模型:
defmodule Address do
use Ecto.Model
schema "addresses" do
field :zip, :string
field :country, :string
# snip
end
@countries_requiring_zip ~w(US) # snip
def changeset(model, params \ :empty) do
model
|> cast(params, ~w(country), ~w(zip))
|> validate_zip
end
defp validate_zip(changeset) do
if get_field(changeset, :country) in @countries_requiring_zip do
# ????
end
changeset
end
end
我想将 zip
标记为必需而不是可选,但前提是该国家/地区在白名单中,但我想不出一种简洁的方式来编写验证。如何添加该约束?
没有明确的函数要求 cast
之外的字段。您可以使用 validate_length/3 函数并覆盖 ':message' 选项。
validate_length(changeset, :zip, min: 1, message: "is required when country is US")
您也可以简单地定义多个转换:
def changeset(model, params \ :empty) do
model
|> cast(params, ~w(country), ~w())
|> cast_by_country(params)
end
defp cast_by_country(changeset, params) do
case get_field(changeset, :country) do
"US" -> cast(changeset, params, ~w(zip), ~w())
_ -> cast(changeset, params, ~w(), ~w(zip))
end
end
get_field/2
将从更改中读取一个值,如果没有则回退到结构一。这是变更集的最大好处:它只是数据结构,您可以使用常规的 Elixir 代码进行条件检查、验证等。直接编写、阅读和测试。 :)