mjswartz
mjswartz

Reputation: 743

Grails validation on an associated 'hasMany' object

I'm having a validation issue very similar to what is described here

https://schneide.wordpress.com/2010/09/20/gorm-gotchas-validation-and-hasmany/

but with an important difference that I don't have (or want) a List<Element> elements field in my domain. My code is

class Location {

    static hasMany = [pocs: LocationPoc]

    Integer id
    String address
    String city
    State state
    String zip
    ...

    static mapping = {
        ...
    }

    static constraints = {  
        def regEx = new RegEx()

        address blank: true, nullable: true, matches: regEx.VALID_ADDRESS_REGEX 
        city blank: true, nullable: true 
        state blank: true, nullable: true
        zip blank: true, nullable: true
        ...
    }
}

however, if I save/update a location with a bunk POC (point of contact), I get some wild errors. I would like to validate the POC's when I save/update a location, but I'm not exactly sure how. I've tried a few variations of

pocs validator: {
    obj -> obj?.pocs?.each {
        if (!it.validate()) {
            return false
        }
    }
    return true
}

to no avail. Is this possbile without creating a new field on my domain, List<LocationPoc> pocs?

Upvotes: 3

Views: 902

Answers (2)

burns
burns

Reputation: 1121

Validation doesn't automatically cascade through hasMany associations. In order to get free validation, the other side of the relationship needs to belong to Location.

You didn't include your LocationPOC class, but if you modify

Location location

to

static belongsTo = [location: Location]

Then you will get cascading validation when you save your Location object.

If you can't set the belongsTo property on LocationPoc, and need to use the custom validator, the syntax is a bit different than the answer above.

pocs validator: {val, obj ->
    val?.inject true, {acc,item -> acc && item.validate()}
}

the three arguement version of validate expects you to add errors to the errorCollection. https://grails.github.io/grails2-doc/2.5.6/ref/Constraints/validator.html

Plus using a return statement inside of .each doesn't work like the above example. It just exits the closure and starts the next iteration. The validator from the other answer was just returning val (the result of val.each is just val) You need to spin through the entire collection looking for non valid options.

Upvotes: 0

Joshua Moore
Joshua Moore

Reputation: 24776

You're close. The issue is you need to target the property you want to validate instead of using the object reference. It should look like this:

pocs validator: { val, obj, err ->
  val?.each {
    if (!it.validate()) return false
  }
}

Upvotes: 1

Related Questions