Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using traits and constraints with grails 3.x domain objects

Is it possible somehow to create a trait with fields and constraints for those fields and then create domain classes that implement that trait and pick up the fields with constraints?

I have code that essentially looks like:

trait Shared {
  String sharedField

  static constraints = {
    sharedField nullable: true
  }
}

class ImplementingClass implements Shared {
  ...
}

Saving an instance of ImplementingClass with a null sharedField is then rejected with a constraint violation.

Is it possible to do this? Is there an alternative syntax that is required to use constraints and other GORM constructs in traits implemented by domain objects?

like image 696
Joseph Downing Avatar asked Nov 09 '22 14:11

Joseph Downing


1 Answers

I had the same problem and I looked at the source code of Grails and made some experiments.

importFrom(Shared) will not work because the Grails looks for a constraints field via clazz.getDeclaredFields() what results in an empty array for traits.

Now you have two options:

  1. Make a Java/Groovy Class wich looks like your trait, but only contains the properties and constraints map

    class SharedConstraints { String sharedField

     static constraints = {
       sharedField nullable: true
     }
    

    }

Now you can use SharedConstraints with importFrom

  1. Create a groovy script for the constraints. This feature is mainly used for Java domain classes but also can be used for traits.

Create a SharedConstraints.groovy in the same package:

constraints = {
    sharedField nullable: true
}

If you use IntelliJ with Grails 3.0 (maybe other versions too) the script must be placed in the resources folder. If you place the file in the src/java folder as described in the Grails documentation the script gets compiled and will not workintelliJ screenshot

Also note this bug https://github.com/grails/grails-core/issues/10052

like image 126
Andreas Avatar answered Nov 15 '22 07:11

Andreas