Ecto changesets and regex sanitising

I am trying to sanitise optional field tags into URL safe words.

The best place is in my changeset I have thought and implemented the following fuction.

I am not a fan of if,else and default false in there, is there a cleaner, shorter way to implement the following?

I couldn’t find any examples

def trim_tags(changeset) do
    tags = get_change(changeset, :tags, false)

    if tags do
      put_change(changeset, :tags, String.replace(tags, ~r/[^A-Za-z0-9-_,]+/, ""))
    else
      changeset
    end
  end

Ecto.Changeset.update_change/3 sounds like it should do what you want:

def trim_tags(changeset) do
  update_change(changeset, :tags, &String.replace(&1, ~r/[^A-Za-z0-9-_,]+/, ""))
end

This has one behavioral difference: explicitly changing tags to nil will fail in the second version, where it would go down the else branch in the original.

You could mitigate that by defining a nil-tolerant cleanup function:

def trim_tags(changeset) do
  update_change(changeset, :tags, &split_tags/1)
end

defp split_tags(nil), do: nil
defp split_tags(tags), do: String.replace(tags, ~r/[^A-Za-z0-9-_,]+/, "")
2 Likes

yes definitely should have gone with function overloading in a FP language rather than if else :slight_smile: thank you!

You have a typo in the regex ~r/^A-Za-z0-9-_,]+/ missing [ at the beginning please update for whoever is visiting the thread :slight_smile: