在变更集中的多个字段上应用 Ecto validate_length

Applying Ecto validate_length on multiple fields in Changeset

Ecto 3.2.5,Phoenix 1.4.11,Elixir 1.9.4

我有一个看起来像这样的 Ecto Changeset。我有许多字段,我想 运行 validate_length 具有相同的最大长度。

my_model
|> validate_required(required_fields())
|> validate_length(:field, max: 255)
|> validate_length(:another_field, max: 255)
# More of the same validate_length

我没有一一列出,而是在上面的管道之后用我的变更集尝试了一些类似的东西,但没有成功。

Enum.map([:field, :another_field], fn string_field ->
  Ecto.Changeset.validate_length(ch, string_field, max: 255)
end)

validate_length 默认情况下只接受一个字段,那么如何在不逐行的情况下验证多个字段的长度 validate_length?

Enum.map/2 将不起作用,因为您实际要执行的是通过验证 减少 许多字段的变更集。

像下面这样简单地声明普通的私有函数

@spec validate_length_many(
  changeset :: Ecto.Changeset.t(), fields :: [atom()]
) :: Ecto.Changeset.t()
defp validate_length_many(
  %Ecto.Changeset{} = changeset, fields
) when is_list(fields) do
  Enum.reduce(fields, changeset, fn field, changeset ->
    validate_length(changeset, field, max: 255)
  end)
end

并将其用作

my_model
|> validate_required(required_fields())
|> validate_length_many(~w[f1 f2]a)

或调用 Enum.reduce/3 directly (it won’t pipe well because the first argument in the call to Enum.reduce/3 将是一个字段列表)。

changeset = validate_required(my_model, required_fields())
Enum.reduce([:f1, :f2], changeset, fn field, changeset ->
  validate_length(changeset, field, max: 255)
end) #⇒ changeset