I added a custom validator in domain class for a property. But whenever I run the unit test and run validate() method I get an error message that the property could not be recognized in the class. when I remove my custom validator everything is working properly.
Thanks your your help!
class Region {
int identifier
BigDecimal leftUpLatitude
BigDecimal leftUpLongitude
BigDecimal rigthDownLatitude
BigDecimal rigthDownLongitude
static constraints = {
identifier unique:true, validator: {return identifier > 0}
leftUpLatitude min:-90.00, max:90.00
leftUpLongitude min:-180.00, max:180.00
rigthDownLatitude min:-90.00, max:90.00
rigthDownLongitude min:-180.00, max:180.00
}
boolean isValidRegion(){
if ((leftUpLatitude > rigthDownLatitude) && ( leftUpLongitude < rigthDownLongitude))
return true
else
return false
}
String toString(){
return "${identifier}"
}
}
Accessing the objects properties in a custom validator is a little bit different than just referencing the property. The validator closure takes one or two parameters, 1) the current property's value and 2) the object itself, if you need access to the rest of the object.
validator: { val -> val > 0 }
Related
I have a grails domain class with an embedded object, I want to validate the embedded object's attributes only while updating.
I know I can do this on a normal grails domain class by using a custom validator and checking if the domain's class id is not null.
I can't do this because of the lack of an id on an embedded object.
There is a little example of what I want to do.
//This is on domain/somePackage/A.groovy
class A{
B embeddedObject
static embedded = ['embeddedObject']
static constraints = {
embeddedObject.attribute validator:{val, obj-> //The app fails to start when this code is added!!
if(obj.id && !val) //if the id is not null it means the object it's updating...
return 'some.error.code'
}
}
}
//this class is on src/groovy/somePackage/B.groovy
class B{
String attribute
static constraints={
attribute validator:{val,obj->
if(obj.id && !val) //This will fail too! because the lack of an id on this object....
return 'some.error.code'
}
}
}
Is there a way to get the id of the 'parent' on the embedded object??
Any help will be appreciated
way too complicated:
class A{
B embeddedObject
static embedded = ['embeddedObject']
static constraints = {
embeddedObject validator:{ val, obj ->
if( obj.id && !val.attribute )
return 'some.error.code'
}
}
}
I have a Command Object as follows :
class TestCreationCommand {
String title
List testItems = [].withLazyDefault {new VocabQuestion()}
static constraints = {
title(blank:false,maxLength:150)
testItems( validator: { ti ->
ti.each {it.validate()}
} )
}
}
Test Items is a list of VocabQuestion objects. VocabQuestion is as follows :
class VocabQuestion {
static constraints = {
question(blank:false,maxLength:150)
answer(blank:false,maxLength:40)
}
static belongsTo = [vocabularyTest: VocabularyTest]
String question
String answer
}
I'm attempting to validate the constraints on the VocabQuestion using a custom vaildator ( in the constraints of the Command class above ), but I keep getting the following error message.
Return value from validation closure [validator] of property [testItems] of class [class vocabularytest.TestCreationCommand] is returning a list but the first element must be a string containing the error message code
I have had many different attempts at this .....
I am not sure what the message is telling me or how to go about debugging what the return value from the closure is.
Can anyone provide me any pointers?
You are not returning what Grails understands. You can't expect to just return anything and have Grails know what to do with it. Return a boolean or an error string.
static constraints = {
title(blank:false,maxLength:150)
testItems( validator: { ti ->
Boolean errorExists = false
ti.each {
if (!it.validate()) {
errorExists = true
}
}
errorExists
})
}
Check out this SO question It might be the format of the validator you need.
The .every will return a boolean.
I am trying to write a generic custom validator for a property, to make it generic i need a reference to the field name within the closure, the code is as follows
In config.groovy
grails.gorm.default.constraints = {
nameShared(validator: {val, obj, errors->
Pattern p = Pattern.compile("[a-zA-Z0-9-]{1,15}")
Matcher m = p.matcher(val)
boolean b = m.matches()
if(!b)
errors.rejectValue('name', "${obj.class}.name.invalid", "Name is invalid")
})
in My domain class
class Student{
String name
static constraints = {
name(shared:'nameShared')
}
}
class Teacher{
String firstName
String lastName
static constraints = {
firstName(shared:'nameShared')
}
}
I want to use the same validator for both name and firstName, but since i am hardcoding the fieldName in the validator, it will always work for name and not firstName, so i want to know if there is anyway i can get a reference to the fieldname and make the validator generic, please help
You could use the variable propertyName to get the name of the validated property.
From the grails docs:
The Closure also has access to the name of the field that the constraint applies to using propertyName
myField validator: { val, obj -> return propertyName == "myField" }
You could wrap your validator-closure inside another function like this:
def getValidator(myValue) {
return { val, obj, errors ->
// make use of myValue
}
}
myField validator: getValidator('foo')
I'm using the Grails Webflow plugin. Here are the domain objects I'm working with:
class Foo implements Serializable {
String fooProp1,
fooProp2
static constraints = {
fooProp2 nullable: false
}
}
class Bar implements Serializable {
Foo fooObject
static constraints = {
fooObject nullable: false
}
}
At a point in the webflow, I need to make sure that fooObject.fooProp1 is not null. If it is, I want to throw an error and force the user to supply it with a value. I tried using validate() to do this (on both the Bar and Foo objects), but since fooProp1 has the nullable:true property, it passes validation. Any ideas?
You can probably do this in the Web Flow by adapting the following code:
if(fooObject.fooProp1 == null) {
fooObject.errors.rejectValue('fooProp1', 'nullable')
}
The second argument to that method, 'nullable', might be different for your situation. You'll just need to set it to the message code (from message.properties) to display the error message that you want.
Have a look here for more ways to use reject() and rejectValue().
I have a property that can be nullable or required depending on the status of another variable.
class Person{
name()
civilStatus(inList:['Single','Married','Divorced','Widowed'])
partnerOrSpouse()
}
the partnerOrSpouse property is nullable or not depending on the value of the civilStatus property.
You can use a custom validator. Using the two-parameter version, the first is the value being validated and the second is the domain class instance. You can refer to other properties via the 'obj' parameter:
class Person {
...
static constraints = {
name()
civilStatus inList:['Single','Married','Divorced','Widowed']
partnerOrSpouse validator: { val, obj ->
if (obj.civilStatus == 'Single') {
return 'some.error.code'
}
}
}
}