Gideon
Gideon

Reputation: 1567

Including the max and offset criteria inside GORM criteriaBuilder returns an error

Can I make this code shorter?

if(count == null && from = null) {
    creditAdviceList = CreditAdvice.findAll {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}
else if(count != null && from == null) {
    creditAdviceList = CreditAdvice.findAll(max: count) {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}
else if(count == null && from != null) {
    creditAdviceList = CreditAdvice.findAll(offset: from) {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}
else if(count != null && from != null) {
    creditAdviceList = CreditAdvice.findAll(max: count, offset: from) {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}

You see, its a series if statement for each possible scenario. Imagine if one would to use also order and cache in the parameter- there will be basically 16 unique if statements!

I've tried this [more] shorter code:

creditAdviceList = CreditAdvice.findAll {
    ilike('id', "%$idFilter%")
    .....
    ilike('statusCode', statusCodeFilter)

    if(count != null) {
        maxResults(count)
    }
    if(from != null) {
        firstResult(from)
    }
}

But it gives me an error:

...No signature of method: grails.gorm.DetachedCriteria.maxResults() is applicable for argument types: (java.lang.Integer)...

I tried to convert offset to int, Integer, String, etc. I also omit the if statement inside the criteria, but the same error message occur.

Upvotes: 3

Views: 1285

Answers (2)

Deigote
Deigote

Reputation: 1761

As far as I see, the only difference is the pagination options. If my eyes are not tricking me, yes, you can:

Map paginationArgs = [max: count, offset: from].findAll { 
   it.value != null 
}
List<CreditAdvice> creditAdviceList = CreditAdvice.findAll(paginationArgs) {
   ilike('id', "%$idFilter%")
   .....
   ilike('statusCode', statusCodeFilter)
}

You can style it differently, but basically you can build the pagination arguments first, and pass them to the findAll. No duplicated code, clearer responsability of the conditions. To clarify, I'm adding all the options and then filtering them to exclude the ones that are null.

Upvotes: 1

cfrick
cfrick

Reputation: 37033

findAll with a closure passed is using a DetachedCriteria internally, which is not the same as the result you would get from createCriteria mentioned in the docs. If groovy would find "something close" enough, it would tell you in the error message. The easiest way to deal with your max/from demands would be with simply with a map (which is the first argument passed). E.g.:

def qcfg = [:]
if (count) {
    qcfg.count = count
}
if (from) {
    qcfg.offset = from
}
creditAdviceList = CreditAdvice.findAll(qcfg) { ... }

mix, match, extract, shorten as you see fit

Upvotes: 2

Related Questions