Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusing part of Grails criteria closure

I have a fairly large criteria closure in my Grails application, and I would like to reuse part of it in several places in my application. Rather than duplicating the section I need to reuse, I'd like to define this as a separate closure and reference it wherever it is needed, but I am struggling a bit with the syntax.

This is a simplified / cut down version, but essentially my criteria looks something like this:

def criteriaClosure = {
    and {
        // filtering criteria that I'd like to reuse in lots of places
        or {
            names.each { name ->
                sqlRestriction(getFilteringSql(name), [someId])
            }
        }

        if (isOrganisationChild(childDefaultGrailsDomainClass)) {
            sqlRestriction(getFilteringSql(domain), [someArg])
        }

        // filtering criteria that's specific to this particular method
        sqlRestriction(getSomeOtherSql(), [someOtherArg])
    }
}

def criteria = domain.createCriteria()
def paginatedList = criteria.list([offset: offset, max: max], criteriaClosure)

I've tried defining the part of the closure I want to reuse as a variable, and referencing it in my criteria closure, however the restrictions it defines don't seem to be applied.

def reusableClosure = {
    and {
        or {
            names.each { name ->
                sqlRestriction(getFilteringSql(name), [someId])
            }
        }

        if (isOrganisationChild(childDefaultGrailsDomainClass)) {
            sqlRestriction(getFilteringSql(domain), [someArg])
        }
    }
}

def criteriaClosure = {
    and {
        reusableClosure() //this doesn't seem to work
        sqlRestriction(getSomeOtherSql(), [someOtherArg])
    }
}

I'm sure this must be a pretty straightforward thing to do, so apologies if it's a daft question. Any ideas?

like image 906
rcgeorge23 Avatar asked Nov 25 '13 13:11

rcgeorge23


1 Answers

I think you have to pass the delegate down to the reusableClosure, ie:

def criteriaClosure = {
    and {
        reusableClosure.delegate = delegate
        reusableClosure()
        sqlRestriction(getSomeOtherSql(), [someOtherArg])
    }
}
like image 151
tim_yates Avatar answered Sep 21 '22 02:09

tim_yates