Domain Class Validation

Example

class User {
   String login
   String password
   static constraints = {
          login(size:5..15,blank:false,unique:true)
          password(size:5..15,blank:false)
   }
}
In the reference that follows, className.propertyName.validationConstraint refers to the error message codes defined in _grails-app/i18n/message.properties_.

For example, referring to the above class, the error message might be defined as: _user.login.blank=Please enter a login_

{_}Since 0.5. You could use common pattern "className.propertyName.constraintName.error" for all constraints, example: "user.login.blank.error=Please enter a login"._

Validation Constraint Reference

blank

Usage: set to false if a string value cannot be blank
Note: an empty form field will appear in the request parameters as an empty string, not as null. Keep this in mind when setting domain fields directly form request parameters
Remember, there are some blank values that are not null, for example an empty String or a Tab. For null validations see #nullable constraint.
Example:

login(blank:false)
Error message code: className.propertyName.blank

creditCard

Usage: set to true if a string should be a credit card number Example:

cardNumber(creditCard:true)
Error message code: className.propertyName.creditCard.invalid

email

Usage: set to true if a string value is an email address Example:

contactEmail(email:true)
Error message code: className.propertyName.email.invalid

password

Usage: set to true if a string value is a password Example:

password(password:true)
Error message code: className.propertyName.password.invalid

inList

Usage: constrains a value so that it must be contained within the given list Example 1:

name(inList:["Joe", "Fred", "Bob"] )

Example 2:

name(inList:[1 as Short, 2 as Short, 3 as Short] ) // Short could be switched to Double etc

Error message code: className.propertyName.not.inList

This constraint influences schema generation.

length

Deprecated in 0.4. Removed in 0.5. Use #size instead.

Usage: Uses a Groovy range to restrict the length of a string or array Example:

login(length:5..15)
Error message code: className.propertyName.length.toolong, className.propertyName.length.tooshort

This constraint influences schema generation.

matches

Usage: Applies a regular expression against a string value Example:

login(matches:"[a-zA-Z]+")
Error message code: className.propertyName.matches.invalid

max

Usage: sets the maximum value of a class that implements java.lang.Comparable. The same type needs to be used as the property itself. Example:

age(max:new Date())
price(max:999F)
Error message code: className.propertyName.max.exceeded

This constraint influences schema generation.

maxLength

Deprecated in 0.4. Removed in 0.5. Use #maxSize instead.

Usage: sets the maximum length of a string or array property Example:

login(maxLength:5)
Error message code: className.propertyName.maxLength.exceeded

This constraint influences schema generation.

maxSize

Usage: sets the maximum size of a collection or number property

Deprecated in 0.5 for number properties. Use #max instead.

Example:

children(maxSize:25)
Error message code: className.propertyName.maxSize.exceeded

This constraint influences schema generation.

min

Usage: sets the minimum value of a class that implements java.lang.Comparable. The same type needs to be used as the property itself. Example:

age(min:new Date())
price(min:0F) // or price(min:0.0 as Double)
Error message code: className.propertyName.min.notmet

This constraint influences schema generation.

minLength

Deprecated in 0.4. Removed in 0.5. Use #minSize instead.

Usage: sets the minimum length of a string or array property Example:

login(minLength:5)
Error message code: className.propertyName.minLength.notmet

This constraint influences schema generation.

minSize

Usage: sets the minimum size of a collection or number property

Deprecated in 0.5 for number properties. Use #min instead.

Example:

children(minSize:5)
Error message code: className.propertyName.minSize.notmet

This constraint influences schema generation.

notEqual

Usage: validates that a property is not equal to the specified value Example:

login(notEqual:"Bob")
Error message code: className.propertyName.notEqual

nullable

Usage: set to false if the property value cannot be null
Note: an empty form field will appear in the request parameters as an empty string, not as null. Keep this in mind when setting domain fields directly form request parameters
Remember, there are some blank values that are not null, for example an empty String or a Tab. For blank validations see #blank constraint.
Example:

age(nullable:true)
Error message code: className.propertyName.nullable

Default: By default, all fields are not nullable (required).

range

Usage: Uses a Groovy range to ensure that a property's value occurs within a specified range Example:

age(range:minAge..maxAge)
Error message code: className.propertyName.range.toosmall or className.propertyName.range.toobig

This constraint influences schema generation.

scale

_Since: 0.4_ Usage: Set to the desired scale for floating point numbers (i.e., the number of digits to the right of the decimal point). This constraint is applicable for properties of the following types: java.lang.Float, java.lang.Double, and java.math.BigDecimal (and its subclasses). When validation is invoked, this constraint determines if the number includes more nonzero decimal places than the scale permits. If so, it automatically rounds the number to the maximum number of decimal places allowed by the scale. This constraint does not generate validation error messages. Example:

salary(scale:2)
Error message code: N/A

This constraint influences schema generation.

size

Usage: Uses a Groovy range to restrict the size of a collection or number or the length of a String

Deprecated in 0.5 for number properties. Use #range instead.

Example:

children(size:5..15)
Note: currently it could not be used in addition to blank:true or nullable:true contraints, a custom validator may be added to perform this kind of constraints (if not null then...)

Error message code: className.propertyName.size.toosmall or className.propertyName.size.toobig

This constraint influences schema generation.

unique

Usage: set to true if the property must be unique (this is a persistent call and will query the database) Example:

login(unique:true)
Note: be aware that it's possible (though uncommon in practice) for a uniqueness constraint validation to pass but a subsequent save of the data to fail due to a uniqueness constraint enforced at the database level. The only way to prevent this would be to use the SERIALIZABLE transaction isolation level (bad for performance) or just be prepared to get an exception to this effect at some point. [{}Since 0.5] Scope of unique constraint can be specified. "Scope" - is a name of another property of the same class, or list of such names. Semantic in these cases is: pair of constrained property value and scope property value must be unique (or combination of constrained property value and all scope property values must be unique).

Example:

group(unique:'department')
In the above example group name must be unique in one department but there might be groups with same name in different departments.

Another example:

login(unique:['group','department'])
In this example login must be unique in group and department. There might be same logins in different groups or different departments.

Error message code: className.propertyName.unique

url

Usage: set to true if a string value is a URL address Example:

homePage(url:true)
Error message code: className.propertyName.url.invalid

validator

Usage: set to a Closure to use custom validation. A single or no parameter Closure receives the value, a two-parameter Closure receives the value and object reference.

Since 0.5.5 a three-parameter Closure receives the value, object reference and the errors object.

The closure can return:

  • null or true to indicate that the value is valid
  • false to indicate an invalid value and use the default message code
  • a string to indicate the error code to append to the "classname.propertName." string to display an error
  • a list containing a string as above, and then any number of arguments following it, which can be used as formatted message arguments indexed at 3 onwards. See grails-app/i18n/message.properties to see how the default error message codes use the arguments.
If the closure is a three-parameter closure the return value is ignored and the closure is expected to populate the errors object.

Examples:

even( validator: {
   return (it % 2) == 0
})

password1( validator: { val, obj -> obj.properties['password2'] == val })

magicNumber( validator: someClosureWithTwoParameters)

// This one assumes you have an error message defined like: // classname.propertyName.custom.error=My error shows arguments {3} and {4} for value {0} otherProperty( validator: { return ['custom.error', arg1, arg2] } )

// The following example does not use custom validation. // A custom message may be defined in messages.properties: // user.login.blank=Please enter a login // which will be used instead of default.blank.message class User { String login static constraints = { login(blank:false) } }

// In the following example, custom validation is used: // user.login.validator.invalid=Please enter a login class User { String login static constraints = { login(validator: { return (it.length != 0) }) } }

// The following might define the error message as: // user.login.invalid.bountyhunter=Invalid bounty hunter ({2}) tried to log in. (Class name = {1}. Property name = {0}) class User { String login static constraints = { login(validator: { if (!it.startsWith('boba')) return ['invalid.bountyhunter'] }) } }

Error message code (default): className.propertyName.validator.invalid


For custom error messages, you can also return a custom value to be displayed in the error message. This is usually parameter number 3.

For instance, in messages.properties: source.reportName.invalid=For source type {3}, report name must be specified.

And in the custom validator:

reportName(maxSize:255, nullable: true, validator: { val, obj ->
  if(obj.reportName == null && (obj.sourceName == 'Buddecom Report')){
      return ['source.reportName.invalid', obj.sourceName]
  }	        
})


No Comments Yet

Post a Comment