Search code examples
elixirecto

Remove trailing and leading whitespaces with Ecto changeset


Is there a built-in way in Ecto to remove trailing and leading whitespaces of fields in Ecto.Changeset when calling changeset/2 before inserting it to the database?


At the moment, I am adding two custom functions to my schema for data filtering to improve data integrity:

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

The function(s) can then be piped in the changeset/2 function with, e.g.

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

Since I think this is a common use-case I was wondering if there isn't a function that already provides this functionality?

If this functionality is not yet provided in Ecto, then from the Ectos API point of view, it would be convenient to add such functions and by naming them filter_trim and filter_... I guess?


Solution

  • I think it's best to trim input before running validations. Also, update_change will only perform the change if there is a change for the given key.

    This leads to slightly more streamlined code:

    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])