使用 Ecto 变更集删除尾随和前导空格

问题描述 投票:0回答:3

Ecto 是否有内置方法可以在将其插入数据库之前调用

Ecto.Changeset
时删除
changeset/2
中字段的尾随和前导空格?


目前,我正在向架构中添加两个自定义函数以进行数据过滤,以提高数据完整性:

defp trim_fields(changeset, fields) do
  Enum.reduce(fields, changeset, &trim(&2, &1))
end

defp trim(changeset, field) do
  if get_change(changeset, field) do
    update_change(changeset, field, &String.trim/1)
  else
    changeset
  end
end

然后可以将函数通过管道传输到

changeset/2
函数中,例如

def changeset(%Customer{} = customer, attrs) do
  |> cast(attrs, [:first_name, :last_name])
  |> validate_required([:first_name], [:last_name])
  |> trim_fields([:first_name, :last_name])
end

因为我认为这是一个常见的用例,所以我想知道是否没有一个函数已经提供了此功能?

如果 Ecto 中尚未提供此功能,那么从 Ectos API 的角度来看,添加此类功能并将其命名为

filter_trim
filter_...
我猜会很方便?

elixir ecto
3个回答
22
投票

我认为最好在运行验证之前修剪输入。此外,

update_change
仅当给定键发生更改时才会执行更改。

这会导致代码稍微简化:

changeset
|> cast(attrs, [:first_name, :last_name])
|> update_change(:first_name, &String.trim/1)
|> update_change(:last_name, &String.trim/1)
|> validate_required([:first_name, :last_name])

0
投票

为什么不简单地使用

:trim

changeset
|> cast(attrs, [:first_name, :last_name])
|> validate_required([:first_name, :last_name], [trim: true])

文档validate_required/3


0
投票

我想扩展 zwippie 的精彩答案。

正如文档指出的,如果该字段被清除,该值可能是

nil
。因此,我会使用这样的东西:

def changeset(%Customer{} = customer, attrs) do
  customer
  |> cast(attrs, [:first_name, :last_name])
  |> update_change(:first_name, &trim/1)
  |> update_change(:last_name, &trim/1)
  |> validate_required([:first_name, :last_name])
end

defp trim(binary) when is_binary(binary), do: String.trim(binary)
defp trim(nil), do: nil

如果你有很多字段想要进行修剪,我会考虑定义一个辅助函数

update_changes/3
(类似于你的
trim_fields/2
):

def changeset(%Customer{} = customer, attrs) do
  customer
  |> cast(attrs, [:first_name, :last_name])
  |> update_changes([:first_name, :last_name], &trim/1)
  |> validate_required([:first_name, :last_name])
end

defp update_changes(changeset, keys, function) do
  Enum.reduce(keys, changeset, fn key, set -> update_change(set, key, function) end)
end
© www.soinside.com 2019 - 2024. All rights reserved.