开发者

reuse Criteria in Grails Controller

开发者 https://www.devze.com 2023-02-12 17:44 出处:网络
typically you have the following last line in a Grails generated Controller list method: [userInstanceList: User.list(params), userInstanceTotal: User.count()]

typically you have the following last line in a Grails generated Controller list method:

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

if I want to restrict the users by a specific criteria it looks like

[userInstanceList: User.list(params) {
   ilike('login', '%test%')
 }, userInstanceTotal: Us开发者_开发知识库er.count() {
   ilike('login', '%test%')
 }]

but this violates the DRY principle - what would be the best way to reuse the criteria closure?


Paged results from a criteria builder (the result class is PagedResultList) have a property, totalCount, which you can use just like you were calling count() on the same criteria:

def userInstanceList = User.createCriteria().list(params) {
    ilike 'login', '%test%'
}
[userInstanceList: userInstanceList, userInstanceTotal: userInstanceList.totalCount]


Another approach for this situation (the need to reuse same logic inside various different criteria queries), could be the use of groovy closures, as you stated in the title of your post.

Your particular case is better solved using the totalCount property of the PagedResultList, just as Dana posted in her answer. But you may come in more complex scenario where you have to reuse logic inside criteria. For a similar situation, I've successfully tried the following solution. Using your case just as an example:

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

Where builder in iLikeLoginClosure is a reference to the criteria builder object within which the closure is called. Furthermore, inside the iLikeLoginClosure you can use variables of the same scope within the closure is defined.

This was inspired by this article: http://mrhaki.blogspot.com.ar/2010/06/grails-goodness-refactoring-criteria.html from MrHaki's excellent blog.


You can use named queries.

In your domain class:

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

In your controller:

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

Or (I'm not 100% sure this will work, but try it.):

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号