Geek & Roll - Blog Archive » Uso de enum en Grails

Uso de enum en Grails

Cesar May 18th, 2009 programacion 5 comentarios

O “El diablo está en los detalles”.

Recientemente he estado usando Grails como framework para desarrollo Web con Java y, francamente, estoy bastante sorprendido. Realmente es un boost a la productividad, tanto que una vez que terminé mi diagrama UML del dominio de mi primera aplicación en Grails y comencé a programar las clases de dominio, no podía creer que esas mismas clases fueran las que se usarían para persistir en la base de datos. No hay que crear archivos hbm.xml ni configurar Spring. Sólo crear la clase del dominio, y ya.

Después de varias sesiones nocturnas de un par de horas leyendo sobre Grails, y viendo el código que genera el scaffolder incluído, empecé a crear mis controladores, vistas, refactorizando el modelo. Todo iba bien hasta que me topé con la necesidad de usar datos enumerados (enums).

La solución en sí es sencilla. El problema es que no existe documentación suficiente para utilizar enums con Grails. Después de consultar distintas fuentes e invertir buena parte de mi Domingo en dar con la solución, aquí les presento el código con el que pueden lograr utilizar enums en Grails.

El propósito de la enumeración en este ejemplo, es asignar una categoría de uso a distintos productos. Para este caso, son productos de belleza (maquillaje y esas cosas) y las categorías abarcan un rango definido de valores (un candidato perfecto para convertirse en un enum). Cabe mencionar que si se espera que el usuario pueda crear sus propias categorías, entonces la solución no es manejar las categorías como un enum.

Primero, creamos una nueva clase de Grails dentro de la carpeta domain. Esta clase va a ser nuestra enum.

public enum Category{
	FACE('Cara'),
	EYES('Ojos'),
	MOUTH('Boca'),
	BRUSHES('Brochas'),
	OTHER('Otra')

	String name

	Category(String name){
		this.name = name
	}
	static list(){
		[FACE, EYES, MOUTH, BRUSHES, OTHER]
	}
	public String toString(){
		return name
	}
}

Muy bonito. Ya sabemos que cada producto puede tener una de 5 categorías. Además, nuestra enumeración recibe una cadena con el nombre de la categoría, y contiene un método estático que nos regresa una lista con las instancias de las categorías presentes en la enumeración.

Ahora veamos el modelo. La clase Product:

class Product {
	String name
	Float basePrice
	Category category
	String imagePath = "images/products/default.jpg"
	Inventory inventory

    	static constraints = {
    		name(size:3..25, blank:false)
    		basePrice(scale:2, nullable:false)
    		category(inList:Category.list(), nullable:false)
    		imagePath(url:true, blank:false)
    		inventory(nullable:false)
    	}
}

Sencillito y carismático. La parte importante es donde se declara la propiedad category como tipo Category (es decir, como una instancia de la enumeración) y en la restricción (constraint). Grails te permite especificar las restricciones para cada una de las propiedades que forman parte de las clases del dominio. En el caso de la propiedad cateogry se le dice que cualquier valor que se le trate de asignar, debe encontrarse en una lista. ¿Qué lista? la que regresa Category.list()

Por último, la vista. La mejor manera de visualizar un enum es con un combobox, dropdown, select o como le quieran llamar. En la vista, utilizamos el siguiente código:

<g:select
	id="category"
	name="category"
	from="${productInstance.constraints.category.inList}"
	value="${productInstance.category}" >
</g:select>

El atributo from le dice de donde obtener la lista de opciones, en este caso de la lista que se le dio a la restricción de la instancia del producto (parece trabalenguas). Value es el valor que se va a usar para despliegue. Internamente Grails llamará al método toString() de Category para determinar el valor.

Y es así como se logra. De tarea hacer que Category.list() regrese la lista generada dinámicamente.

5 Comentarios

Rafyta

May 18th, 2009

Makes me wanna learn Java :D

davisoqt

January 20th, 2010

muy buen ejemplo, yo tambien estoy estudiando grails, pero tengo poca documentacion, si me pudieras decir donde encontrar algo. Realmente lo que me interesa es como programar en lenguaje java y vincularlo con grovy.

Cesar

January 21st, 2010

Yo la documentación que uso es la de referencia de Grails http://www.grails.org/doc/latest/

No entiendo muy bien tu requerimiento, pero si lo que quieres es usar librerías escritas en Java y utilizarlas desde Groovy en un proyecto de Grails eso es muy sencillo, solo pon tus jars en el folder lib y estarán disponibles para tus clases en Groovy.

carlos

October 13th, 2010

hola, tengo un problema al momento de usar enum, resulta que hize lo que indicas en ese blog, y resulta que me sale un mensaje puedes ayudarme con esto. Tengo una clase Producto y un enum Trabajo, el mensaje que me sale es el siguiente.

Failed to convert property value of type java.lang.String to required type com.carza.sgprinting.utils.Trabajo for property trabajo; nested exception is java.lang.IllegalStateException: Cannot convert value of type [/java] to required type [com.carza.sgprinting.utils.Trabajo] for property trabajo: no matching editors or conversion strategy found

grasias de ante mano

Cesar

October 14th, 2010

Asegurate que tus enums se construyan a partir de un String. El error claramente te dice que no puede convertir del tipo String que le pasa la vista, a tu enum.

Haz un comentario:

Es necesario que dejes tu nombre y correo electrónico (no se publicarán).

Si dejas un comentario anónimo, con insultos o ajeno al tema, iremos hasta tu casa y le diremos a tu mamá la cantidad de porno que hay en tu computadora. Si, lo sabemos.