A case for *validating* uniqueness

Here’s an example of validating that an Event has a unique name. There may be ways to improve the code, but at least it shows what I’m talking about.

def validate_unique_name(changeset) do
  name = get_field(changeset, :name)
  if is_binary(name) do
    dups_query = from e in Event, where: e.name == ^name

    # For updates, don't flag event as a dup of itself
    id = get_field(changeset, :id)
    dups_query = if is_nil(id) do
      dups_query
    else
      from e in dups_query, where: e.id != ^id
    end

    dups = dups_query |> Reservations.Repo.all
    if Enum.any?(dups) do
      add_error(
        changeset,
        :name,
        "has already been taken",
        [validation: :validate_unique_name]
      )
    else
      # no duplicates found
      changeset
    end
  else
    # eg, name is nil
    changeset
  end
end
1 Like