Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails validation of a list objects

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 protected]')

// 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?

like image 999
Gareth Davis Avatar asked Jun 24 '09 19:06

Gareth Davis


1 Answers

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.

like image 200
Ted Naleid Avatar answered Sep 28 '22 04:09

Ted Naleid