повторно использовать критерии в Grails Controller - PullRequest
4 голосов
/ 23 февраля 2011

обычно у вас есть следующая последняя строка в методе списка сгенерированных контроллеров Grails:

[userInstanceList: User.list(params), userInstanceTotal: User.count()]

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

[userInstanceList: User.list(params) {
   ilike('login', '%test%')
 }, userInstanceTotal: User.count() {
   ilike('login', '%test%')
 }]

но это нарушает принцип СУХОГО - как лучше всего повторно использовать критерии закрытия?

Ответы [ 3 ]

6 голосов
/ 24 февраля 2011

Постраничные результаты из построителя критериев (класс результата PagedResultList ) имеют свойство totalCount, которое можно использовать так же, как вы вызывали count() по тем же критериям:

def userInstanceList = User.createCriteria().list(params) {
    ilike 'login', '%test%'
}
[userInstanceList: userInstanceList, userInstanceTotal: userInstanceList.totalCount]
3 голосов
/ 18 сентября 2013

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

Ваш конкретный случай лучше разрешить с помощью свойства totalCount PagedResultList, так же как Дана разместила в своем ответе. Но вы можете прийти к более сложному сценарию, когда вам придется повторно использовать логику внутри критериев. Для аналогичной ситуации я успешно попробовал следующее решение. Используя ваш случай в качестве примера:

def iLikeLoginClosure = { builder ->
    builder.ilike('login', '%test%')
}
[
    userInstanceList: User.list(params) {
        iLikeLoginClosure delegate
    },
    userInstanceTotal: User.count() {
        iLikeLoginClosure delegate
    }
]

Где builder in iLikeLoginClosure - это ссылка на объект построителя критериев, внутри которого вызывается замыкание. Кроме того, внутри iLikeLoginClosure вы можете использовать переменные с той же областью действия, что и в замыкании.

Это было вдохновлено этой статьей: http://mrhaki.blogspot.com.ar/2010/06/grails-goodness-refactoring-criteria.html из отличного блога MrHaki.

2 голосов
/ 23 февраля 2011

Вы можете использовать именованные запросы .

В вашем доменном классе:

static namedQueries = {
    ilikeLogin{login->ilike('login', "%$login%")}
}

В вашем контроллере:

def userList = User.ilikeLogin('test').list(params)
def usersCount= User.ilikeLogin('test').count()

Или (я не уверен на 100%, что это будет работать, но попробуйте.):

def query = User.ilikeLogin('test')
def userList = query.list(params)
def usersCount= query.count()
...