Issue
How can I create a detached predicate to send to a method and then do the search with criteria?
Something like this:
def predicate = { eq 'field1', 1 }
search(predicate)
--
def search(predicate) {
return SampleClass.withCriteria() {
predicate
eq 'field2', 2
eq 'field2', 3
}.find()
}
There is a way to do that to avoid ifs inside the criteria?
Solution
There are different approaches you could take. One is represented in the project at github.com/jeffbrown/victorsoarescriteria.
grails-app/domain/victorsoarescriteria/SampleClass.groovy
package victorsoarescriteria
class SampleClass {
String name
String country
int someNumber
}
grails-app/init/victorsoarescriteria/BootStrap.groovy
package victorsoarescriteria
import grails.gorm.transactions.Transactional
class BootStrap {
def init = { servletContext ->
initData()
}
def destroy = {
}
@Transactional
void initData() {
new SampleClass(name: 'Jeff', country: 'United States', someNumber: 42).save()
new SampleClass(name: 'Jake', country: 'United States', someNumber: 21).save()
new SampleClass(name: 'Bill', country: 'United Kingdom', someNumber: 27).save()
def greaterThanFive = search {
gt 'someNumber', 5
}
println "greaterThanFive.size() is ${greaterThanFive.size()}"
def greaterThanTwentyFive = search {
gt 'someNumber', 25
}
println "greaterThanTwentyFive.size() is ${greaterThanTwentyFive.size()}"
}
def search(predicate) {
SampleClass.withCriteria {
predicate.delegate = delegate
predicate()
}
}
}
Output:
~ $ git clone [email protected]:jeffbrown/victorsoarescriteria.git && cd victorsoarescriteria && ./gradlew bootRun
Cloning into 'victorsoarescriteria'...
remote: Enumerating objects: 113, done.
remote: Counting objects: 100% (113/113), done.
remote: Compressing objects: 100% (85/85), done.
remote: Total 113 (delta 15), reused 113 (delta 15), pack-reused 0
Receiving objects: 100% (113/113), 803.93 KiB | 3.77 MiB/s, done.
Resolving deltas: 100% (15/15), done.
> Task :bootRun
greaterThanFive.size() is 3
greaterThanTwentyFive.size() is 2
Grails application running at http://localhost:8080 in environment: development
Answered By - Jeff Scott Brown
Answer Checked By - Willingham (JavaFixing Volunteer)