Grails provides us many inbuilt validators like nullable, blank, email, etc. If you want you can create our own custom validators like:

class CalendarEvent {

    String title
    Date startDate
    Date endDate

    static constraints = {
        endDate nullable: false, validator: { val, obj ->
            if (val <= obj.startDate) {
                return "calendarEvent.endDate.smaller.error"
            }
        }
    }
}

Where calendarEvent.endDate.smaller.error is a code from messages.properties:

calendarEvent.endDate.smaller.error=End date must be greater than start date

Here val represents the property in which validator is applied, i.e. endDate here and obj represents the current object.

But what if we need to pass arguments in custom validator error message?

We can pass the arguments in custom validator by following ways:

  • First Way:
    endDate nullable: false, validator: { val, obj ->
        if (val <= obj.startDate) {
            return ["calendarEvent.endDate.smaller.error", val, obj.startDate]
        }
    }
    

    and message code:

    calendarEvent.endDate.smaller.error=End date {4} is smaller then start date {3}. Please provide end date greater then {3}
    

    Here one question can be: Why I used 3 and 4, why not 0 and 1 as we did in normal message codes?
    Because when we use this way of passing the arguments then:
    0 represents property name (endDate)
    1 represents Class (org.jft.CalendarEvent)
    2 represents the value of the property (any value given by user)

    Because 2 represents property value therefore above example can be reduced to

    endDate nullable: false, validator: { val, obj ->
        if (val <= obj.startDate) {
            return ["calendarEvent.endDate.smaller.error", obj.startDate]
        }
    }
    

    where message code:

    calendarEvent.endDate.smaller.error=End date {3} is smaller then start date {2}. Please provide end date greater then {2}
    
  • Second Way:
    endDate nullable: false, validator: { val, obj, errors ->
        if (val < obj.startDate) {
            Object[] args = [val, obj.startDate]
            errors.rejectValue("endDate", "calendarEvent.endDate.smaller.error", args, "Some Default Message.")
            return false
        }
    }
    

    where errors is errors object and message code:

    calendarEvent.endDate.smaller.error=End date {1} is smaller then start date {0}. Please provide end date greater then {0}
    

Read full documentation here.

Hope this helps 🙂 .