loading...

Discussion on: Groovy delegation strategy for query re-use in Grails

Collapse
david_ojeda profile image
David Ojeda Author

Great question! As far as I know there is no way of doing that without repeating the closure's logic on each Domain 🤔Let me explain myself.

To start off, you can't use a Grails service from a static context, so this would not be possible:

class Customer {
    def listService

    def listView(params) {
        listService.getDomainList(params, this.class)
    }
}
Customer.listView(params)

So, due to this restriction, we could move the service logic to a Groovy Trait and make the Customer class implement it:

trait Listable {

    static def getDomainList(def params) {
        getList.delegate = this.class
        getList(params)
    }

    static def getDomainCount(def params) {
        getCount.delegate = this.class
        getCount(params)
    }

    static private def getList = { def params ->
        createCriteria().list {
            eq 'company', params.company
            if(!params.boolean('showDisabled', false)) {
                eq 'enabled', true
            }
            maxResults params.int('max', 10)
        }
    }

    static private def getCount = { def params ->
        createCriteria().get {
            eq 'company', params.company
            if(!params.boolean('showDisabled', false)) {
                eq 'enabled', true
            }
            projections {
                countDistinct 'id'
            }
        }
    }

}
class Customer implements Listable {

}

Then, you could -teoretically- do:

Customer.getDomainList(params)

I say _teoretically because Trait static methods are not supported on Groovy 2.X, but are coming to Groovy 3.

Maybe there's another way to achieve it, but I can't think of any right now. Do let me know if you find out!

Collapse
aojedal profile image
Arturo Ojeda

Got it! we will have to wait until Groovy 3 is released for that then ,😅, thanks for the detailed explanation.