Ejemplo sencillo y a mano con Grails

De ChuWiki

Ya hemos visto cómo se puede hacer un ejemplo sencillo con Grails dejando que los comandos de grails nos creen prácticamente todo por defecto. Vamos ahora a hacer lo mismo, pero de forma totalmente manual (o casi) un ejemplo sencillo. Aprovecharemos para ir explicando algunos conceptos básicos.

Crear el proyecto[editar]

Primero creamos la estructura de directorios del proyecto. Esto se puede hacer a mano, pero es más cómodo hacerlo directamente con el comando correspondiente de grails. Este comando, además de los directorios, crea los ficheros básicos de configuración de la aplicación que, de mmomento, dejaremos tal cual por defecto.

$ cd un_directorio_cualquiera
$ grails create-app hola-mundo-manual
$ cd hola-mundo-manual

Creamos una clase de nuestro dominio[editar]

Vamos a hacer una aplicación web que nos permita listar, crear, modificar y borrar datos de personas. Lo primero, crear la clase groovy con los datos de nuestra persona. Vamos al directorio grails-app/domain y creamos los subdirectorios para el paquete de la clase y la clase

$ cd grails-app/domain
$ mkdir com
$ mkdir com/chuidiang
$ mkdir com/chuidiang/ejemplos
$ mkdir com/chuidiang/ejemplos/grails
$ gvim com/chuidiang/ejemplos/grails/Persona.groovy

He usado como editor gvim, pero puedes usar el que más te guste o tengas disponible (notepad, gedit, etc). El contenido de Persona.groovy será el siguiente

package com.chuidiang.ejemplos.grails;

class Persona {
   String nombre
   int edad
}

No hemos puesto id de base de datos ni nada parecido, sólo los campos que nos interesan realmente sobre una persona.

Creamos un controlador[editar]

En grails un controlador es una clase que tendrá definidas como atributos una serie de Closures, de esta forma

class PersonaController {
   def listar = {
      ...
   }
   def crear = {
      ...
   }
}

El nombre de la clase debe corresponder con el de la clase del dominio (Persona) y terminar en Controller. Cada una de las Closures que se definen correspondará a una de las vistas (páginas visibles del navegador) y corresponderán a la realización de algún tipo de acción sobre el modelo. Dicho más claramente, PersonaController tendrá una Closure por cada acción que podamos querar realizar sobre Persona (listado de personas, crear una nueva, borrar una existente, modificar, etc). En principio, cada una de estas acciones tendrá una página del navegador asociada (una con el listado de personas, otras con el formulario para crear una persona, otra para modificar sus datos, otra para el borrado, etc).

Vamos con la parte más fácil, el listado de personas.

La Closure listar es la que usaremos para el listado de personas. Para hacer la consulta a base de datos, Grails pone a nuestra disposición varios métodos estáticos de la clase Persona. Algunos de estos métodos son

  • Persona.list() Nos devuelve una lista con todas las Persona en base de datos
  • Persona.findBy..() Devuelve una Persona de acuerdo al método y parámetros que sean. El nombre exacto del método se compone de acuerdo a los campos que hemos creado en Persona. Así, en este caso concreto, existen findByNombre(), findByEdad(), findByEdadAndNombre(), etc. Existen unas reglas de sintaxis sobre cómo componer el nombre de este método correctamente [1]
  • Persona.findAllBy..() Al igual que el anterior, pero devuelve una lista con todas las Personas que cumplen las condiciones.

Para simplificar nuestro ejemplo, usaremos directamente Persona.list() en el controlador. El controlador debe devolver un modelo de datos que la vista sea capaz de pintar de alguna manera. Ese modelo de datos no es más que un Map de Groovy. El código sería este

package com.chuidiang.ejemplos.grails;

class PersonaController {
   def listar = {
      def listadoPersonas = Persona.list()
      return ["personas":listadoPersonas]
   }

El Map de groovy en este caso tiene una clave personas, que se interpreta como String de texto, y el listado de las personas que hemos obtenido en base de datos. No es necesario poner la palabra return, puesto que al dejar el Map en la última línea del método, esto es lo que devolerá. Tampoco es necesrio poner las comillas en personas, puesto que Groovy las sobreentiende por defecto al usarlo como clave de un Map

package com.chuidiang.ejemplos.grails;

class PersonaController {
   def listar = {
      def listadoPersonas = Persona.list()
      [personas:listadoPersonas]
   }

La clase PersonaController.groovy debe estar en el directorio grails-app/controller y ahí dentro, en la estructura de directorios/paquetes correspondiente

$ cd grails-app/controllers
$ mkdir com
$ mkdir com/chuidiang
$ mkdir com/chuidiang/ejemplos
$ mkdir com/chuidiang/ejemplos/grails
$ gvim com/chuidiang/ejemplos/grails/PersonaController.groovy

y el contenido del fichero será el ya mostrado.

La vista[editar]

Ahora vamos a crear la vista. Una vista es una página html que puede llevar código gsp (groovy server pages) o tags específicos de grails. Su extensión es .gsp y normalmente hay que hacer una página .gsp por cada una de las acciones del controlador. La vista debe crearse en el directorio grails-app/views. Ahí debemos crear un directorio con el nombre de la clase del dominio/controlador, en este caso, persona. Y dentro de ese directorio haremos nuestra página listar.gsp, cuyo nombre debe ser el mismo que el de la Closure del controlador

$ cd grails-app/views
$ mkdir persona
$ gvim persona/listar.gsp

En este fichero vamos a mostrar el resultado de la consulta a PersonaController.listar(), es decir, el listado de personas. La parte html de la página podemos hacerlo normalmente. En cualquier momento podemos poner entre tags <% ... %> algo de código groovy. También podemos acceder a variables groovy que estén definidas con ${variable}. Hay más muchas más posibilidades y variantes, pero no vamos a meternos en ello. En el siguiente trozo, vemos un ejemplo de esto que hemos indicado.

<html>
   <head>
      ....
   </head>
   <body>
      <% def variable=3 %>
      <p>La variable vale ${variable}</p>
   </body>
</html>

Vamos ahora a hacer este fichero listar.gsp para mostrar el listado de personas. Si recuerdas, el controllador en su Closure listar devolvía un Map en el que la clave era personas. Esta clave es accesible desde la página gsp, de forma que ${personas} es el valor dentro del Map correspondiente a esa clave, es decir, a una lista de personas. Debemos entonces hacer un código con un bucle para recorrer esto. Una opción es meter código groovy directamente, sabiendo que personas es la variable que contiene la lista de personas

<html>
   <head>
   </head>
   <body>
        <ul>
	<% personas.each { persona ->
           print "<li>"+persona.nombre + "  " + persona.edad+"</li>"
        }
        %>
        </ul>
   </body>
</html>

Otra opción, para no meter tanto código groovy, es usar las etiquetas que grails nos ofrece. En concreto <g:each> que nos permite hacer un bucle de forma similar, pero más al estilo html que al estilo groovy

<html>
   <head>
   </head>
   <body>
        <ul>
        <g:each in="${personas}" var="persona">
           <li>${persona.nombre} ${persona.edad}</li>
        </g:each>
        </ul>
   </body>
</html>

Hemos puesto la etiqueta <g:each> con dos atributos, in y var. En in debemos poner la lista que queremos recorrer, que en este caso es ${personas} y en var el nombre que queremos de variable para referirnos a cada uno de los elementos de la lista. En este caso hemos puesto persona, en singular.

Luego, entre etiquetas <li> hacemos referencia a persona y a sus campos nombre y edad, para mostrarlos en la página, con ${persona.nombre} y ${persona.edad}