Grails validation of a list objects

2019-06-26 07:57发布

问题:

I'm trying to get grails to validate the contents of a List of objects, might be easier if I show the code first:

class Item {
  Contact recipient = new Contact()
  List extraRecipients = [] 

  static hasMany = [
          extraRecipients:Contact
  ]

  static constraints = {}

  static embedded = ['recipient']
}

class Contact {
  String name
  String email

  static constraints = {
    name(blank:false)
    email(email:true, blank:false)
  }
}    

Basically what i have is a single required Contact ('recipient'), this works just fine:

def i = new Item()
// will be false
assert !i.validate() 
// will contain a error for 'recipient.name' and 'recipient.email'
i.errors 

What I'd like also do it validate any of the attached Contact objects in 'extraRecipients' such that:

def i = new Item()
i.recipient = new Contact(name:'a name',email:'email@example.com')

// should be true as all the contact's are valid
assert i.validate() 

i.extraRecipients << new Contact() // empty invalid object

// should now fail validation
assert !i.validate()

Is this possible or do I just have to iterate over the collection in my controller and call validate() on each object in extraRecipients?

回答1:

If I'm understanding the question correctly, you want the error to appear on the Item domain object (as an error for the extraRecipients property, instead of letting the cascading save throw a validation error on the individual Contact items in extraRecipients, right?

If so, you can use a custom validator in your Item constraints. Something like this (this hasn't been tested but should be close):

static constraints = {
    extraRecipients( validator: { recipients ->
        recipients.every { it.validate() } 
    } )
}

You can get fancier than that with the error message to potentially denote in the resulting error string which recipient failed, but that's the basic way to do it.