Grails 3.3.2 доступ к пользовательским мета-ограничениям

В проекте Grails 2.4.4 я смог определить свое собственное пользовательское ограничение (называемое 'SupportToUrl') для свойства домена и использовать его в качестве тега для управления логикой рендеринга в моем GSP.

Код рендеринга GSP:

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

Ограничение класса домена:

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

В обновлении Grails 3.2.x в разделе "Устаревшие Grails и API ConstrainedProperty" обсуждается, как эта функциональность была перемещена. Тем не менее, я не видел ничего в новом API, который ссылается на мета-ограничения.

Мой вопрос: как мне получить доступ к пользовательским ограничениям в Grails 3.3.2?

2 ответа

Решение

Вы можете получить доступ к мета-ограничениям в Grails 3.3.* Из признака Validateable getConstraintsMap().

Пример списка всех свойств, которые поддерживают 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())
            }
        }
    }
}

Имейте в виду, что он видит только те ограничения домена / сущности (абстрактные или нет), которые отмечены этим признаком Validateable. Иерархия классов не будет применяться - когда корневой / суперкласс реализует ее, ограничения верхнего класса все еще не видны, пока вы не отметите его также как Validateable.

Поэтому, основываясь на классе ConstrainedDelegate, я думаю, что короткий ответ заключается в том, что это невозможно. ConstrainedDelegate не предоставляет карту metaConstraints или карту атрибутов DefaultConstrainedProperty. Я оставлю вопрос открытым, хотя в надежде, что кто-то, более осведомленный о дорожной карте архитектуры Grails, сможет объяснить почему.

В то же время я смог взломать решение путем повторного рассмотрения ограничения формата и сравнения формата с моими предопределенными тегами. Хотя я хотел бы услышать другие идеи о том, как достичь своей первоначальной цели, поскольку это явно не то, как формат был предназначен для использования.

Другие вопросы по тегам