Estoy trabajando en la construcción de un createCriteria
dinámicamente. Hasta ahora, todo bien:¿Crear createCriteria en Grails dinámicamente y de manera SECA?
obj
es el objeto (s) de dominio que quiero volver
rulesList
es una lista de los mapas que mantienen el campo para ser buscado en adelante, el operador de usar, y el valor de realizar la búsqueda
def c = obj.createCriteria()
l = c.list (max: irows, offset: offset) {
switch(obj){ //constrain results to those relevant to the user
case Vehicle:
eq("garage", usersGarage)
break
case Garage:
users {
idEq(user.id)
}
break
}
rulesList.each { rule ->
switch(rule['op']){
case 'eq':
eq("${rule['field']}", rule['value'])
break
case 'ne':
ne("${rule['field']}", rule['value'])
break
case 'gt':
gt("${rule['field']}", rule['value'])
break;
case 'ge':
ge("${rule['field']}", rule['value'])
break
case 'lt':
lt("${rule['field']}", rule['value'])
break
case 'le':
le("${rule['field']}", rule['value'])
break
case 'bw':
ilike("${rule['field']}", "${rule['value']}%")
break
case 'bn':
not{ilike("${rule['field']}", "${rule['value']}%")}
break
case 'ew':
ilike("${rule['field']}", "%${rule['value']}")
break
case 'en':
not{ilike("${rule['field']}", "%${rule['value']}")}
break
case 'cn':
ilike("${rule['field']}", "%${rule['value']}%")
break
case 'nc':
not{ilike("${rule['field']}", "%${rule['value']}%")}
break
}
}
}
}
El código anterior funciona bien y es solo un poco detallado con las instrucciones de cambio. Pero, ¿qué ocurre si deseo agregar funcionalidad para elegir hacer corresponder CUALQUIERA de las reglas o TODAS? Tendría que poner las reglas condicionalmente en un or{}
. No puedo hacer algo como
if(groupOp == 'or'){
or{
}
antes de ir a través de la rulesList y luego
if(groupOp == 'or'){
}
}
después. Todo lo que puedo pensar que hacer es repetir el código para cada condición:
if(groupOp == 'or'){
or{
rulesList.each { rule ->
switch(rule['op']){
...
}
}
}
}
else{
rulesList.each { rule ->
switch(rule['op']){
...
}
}
Ahora el código es un aspecto muy descuidado y repetitivo. ¿Supongamos que quiero buscar en una propiedad de una propiedad del objeto de dominio? (Por ejemplo, quiero devolver los vehículos cuyas llantas son de una determinada marca; vehicle.tires.brand, o vehículos cuyos conductores coincidan con un nombre; vehicle.driver.name). Tendría que hacer algo como:
switch(rule['op']){
case 'eq':
switch(thePropertiesProperty){
case Garage:
garage{
eq("${rule['field']}", rule['value'])
}
break
case Driver:
driver{
eq("${rule['field']}", rule['value'])
}
break
}
break
case 'ne':
...
}
gran solución, parece que todavía no estoy dando cuenta y aprovechar todo el poder de maravilloso. Además, para cualquier persona interesada en aprender más sobre createAlias (que no sabía nada de antes) mirar por encima de [aquí] (http://adhockery.blogspot.com/2009/06/querying-by-association-redux.html) – Weezle
Gracias ! createAlias resolvió mi problema. No tengo idea de por qué no se menciona en la página createCriteria de la documentación de Grails. – Ben