Search code examples
erlangelixirphoenix-frameworkectochangeset

How to make Ecto.changeset validate_required accept blank values?


What I'm trying to do is passing an empty string as the value of a field, and validating it to check if not nil. Problem is that validate_required raise error on both nil and blank values. How to make it accept blank values?

schema

  schema "messages" do
    field :user_id, :string
    field :text, :string

    timestamps()
  end

changeset

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:text, :user_id])
    |> validate_required([:text, :user_id])
  end

Solution

  • The behavior of validate_required is unfortunately hardcoded to consider empty as well as whitespace only strings as missing. You can however write a simple function to do the validation:

    def changeset(struct, params \\ %{}) do
      struct
      |> cast(params, [:text, :user_id])
      |> validate_not_nil([:text, :user_id])
    end
    
    def validate_not_nil(changeset, fields) do
      Enum.reduce(fields, changeset, fn field, changeset ->
        if get_field(changeset, field) == nil do
          add_error(changeset, field, "nil")
        else
          changeset
        end
      end)
    end
    

    The function goes over each field, adding error for every field which has a value nil.