Grails 3.3.2 accessing custom meta constraints

269 Views Asked by At

In a grails 2.4.4 project, I was able to define my own custom constraint (called 'supportsToUrl') on a domain property and use it as a tag to control rendering logic in my GSP.

GSP rendering code:

if(domainClass.constraints[p.name].getMetaConstraintValue('supportsToUrl'))

Domain class constraint:

static constraints = {
    embedCode(nullable:true, blank:true, unique:false, display:true, supportsToUrl:true)
}

In Upgrading from Grails 3.2.x in section "Grails Validator and ConstrainedProperty API Deprecated" there is discussion about how this functionality has been moved. However, I did not see anything in the new API that refers to meta constraints.

My question is: How do I access custom constraints in Grails 3.3.2?

2

There are 2 best solutions below

1
On BEST ANSWER

You could access meta constraints still in Grails 3.3.* From Validateable trait getConstraintsMap().

Example list of all properties which supports url (supportsToUrl: true)

Set<String> supportsUrlProperties = new HashSet<>()
Map<String, Constrained> constraints = domainObject.getConstraintsMap()
if(constraints) {
     constraints.values().each { Constrained constrained ->
        DefaultConstrainedProperty propertyToCheck = constrained.properties?.property as DefaultConstrainedProperty
        if(propertyToCheck) {
            def supportsToUrlConstraint = propertyToCheck.getMetaConstraintValue('supportsToUrl')
            if (supportsToUrlConstraint != null && BooleanUtils.isTrue(supportsToUrlConstraint as Boolean)) {
                supportsUrlProperties.add(propertyToCheck.getPropertyName())
            }
        }
    }
}

Be aware, that it sees only constraints from domain/entity (abstract or not) which are marked with this Validateable trait. Class hierarchy won't apply - when root/super class implements it, then top class's constraints still are not visible, until you mark it also as Validateable.

0
On

So based on the ConstrainedDelegate class, I think the short answer is that it's not possible. ConstrainedDelegate does not expose the metaConstraints map or the attributes map of DefaultConstrainedProperty. I will leave the question open though in the hopes that someone more knowledgeable with the Grails architecture roadmap can explain why.

In the meantime, I was able to hack together a solution by re-purposing the format constraint and comparing the format against my predefined tags. Although I'd love to hear other ideas on how to achieve my original goal as this is pretty clearly not how format was intended to be used.