2016-02-11 3 views
1

Я создаю критерии в зависимости от нескольких факторов. В настоящее время я использую вложенные замыкания следующим образом:Grails: используйте несколько затворов внутри другого

Utils.groovy

static def statusAndOrderCriteria = { x -> 
    ... 
    Utils.commonOrderCriteria.delegate = delegate 
    Utils.commonOrderCriteria(x) 
} 

static def commonOrderCriteria = { x -> 
    ... 
} 

Использование:

Alert.createCriteria().list({ 
    Utils.statusAndOrderCriteria.delegate = delegate 
    Utils.statusAndOrderCriteria(x) 
}) 

Я хочу использовать несколько затворов, такие как:

Alert.createCriteria().list({ 
    Utils.firstCriteria(a) 
    Utils.secondCriteria(b) 
    Utils.statusAndOrderCriteria(x) 
}) 

Я не знаю, как этого достичь. Я знаю, что я не могу переписывать объект делегата несколько раз при одном и том же закрытии.

ответ

2

Когда вы строите запрос критериев GORM, делегат замыкания является экземпляром HibernateCriteriaBuilder. Что вы можете сделать, так это изменить свои блокировки Util, чтобы принять этот конструктор в качестве параметра. Затем делегируйте вызовы метода строителю. Вот пример:

class Utils { 
    static def statusAndOrderCriteria = { criteriaBuilder, x -> 
     criteriaBuilder.eq('foo', x) 
     Utils.commonOrderCriteria(criteriaBuilder, x) 
    } 

    static def commonOrderCriteria = { criteriaBuilder, x -> 
     criteriaBuilder.lt('bar', x) 
    } 
} 

Затем вы можете использовать статические замыкания в Util так:

Alert.createCriteria().list({ 
    Utils.firstCriteria(delegate, a) 
    Utils.secondCriteria(delegate, b) 
    Utils.statusAndOrderCriteria(delegate, x) 
}) 

Подсказка: Если затворы были не статические свойства, которые были бы в состоянии избежать постоянно приходится передать делегату, например:

@groovy.transform.TupleConstructor 
class Utils { 
    HibernateCriteriaBuilder criteriaBuilder 

    def statusAndOrderCriteria = { x -> 
     criteriaBuilder.foo() 
     Utils.commonOrderCriteria(x) 
    } 

    def commonOrderCriteria = { x -> 
     criteriaBuilder.bar() 
    } 
} 

Alert.createCriteria().list({ 
    def utils = new Utils(delegate) 

    utils.firstCriteria(a) 
    utils.secondCriteria(b) 
    utils.statusAndOrderCriteria(x) 
}) 
+1

Это фантастика! Мне пришлось искать аннотацию «TupleConstructor» - для кого-либо еще, она предоставляет конструктор, который позволяет использовать «новые Utils (делегат»). – tylerwal

+0

О, спасибо. Вы видели, как другой Groovy строился в астерах? Вся концепция просто потрясающая! –

+0

Я знаком с '@ Builder' AST – tylerwal

Смежные вопросы