Reusing Criteria in a Grails Controller

usually you have the following last line in the list method of the generated Grails controller:

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

if I want to restrict users to certain criteria, it looks like

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

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

+4
source share
3 answers

The paged results from the criteria builder (the PagedResultList result class ) have the totalCount property, which you can use only as you called count() using the same criteria:

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

Another approach for this situation (the need to reuse the same logic in different requests of different criteria) could be to use groovy closures, as indicated in the header of your message.

Your specific case is better solved using the totalCount property for the PagedResultList, just like Dana posted in her answer. But you can come up with a more complex scenario when you need to reuse logic inside criteria. For a similar situation, I have successfully tried the following solution. Using your case as an example:

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

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

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

+3
source

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 that this will work, but try.):

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

Source: https://habr.com/ru/post/1340988/


All Articles