Skip to content

Instantly share code, notes, and snippets.

@mathifonseca
Last active August 29, 2015 14:06
Show Gist options
  • Save mathifonseca/67738809842ab6c1b5ec to your computer and use it in GitHub Desktop.
Save mathifonseca/67738809842ab6c1b5ec to your computer and use it in GitHub Desktop.
Grails

#Grails

##Objetivo Simplifica el desarrollo de aplicaciones Java. Lleva el desarrollo de aplicaciones web al siguiente nivel de abstracción. Construido sobre muchas herramientas que son usadas actualmente y sigue teniendo la flexibilidad para cambiar lo que se desee. Las configuraciones por defecto son usualmente suficientes.

Hibernate El ORM por default del mundo Java
Spring Inversion of Control (IoC) container y framework wrapper
SiteMesh Layout-rendering framework
Tomcat Embeddable servlet container
H2 RDBMS de Java
Log4J Logging

ORM = Mapeo de object-oriented a relational databases IoC = Wiring de dependencia de objetos en runtime

Grails

##Core Ideas

ideas

###Convention over Configuration Pocos archivos de configuración. Muchos valores por defecto. Convenciones por directorio o nomenclatura. La convención no reemplaza a la configuración, es "over" y no "instead of".

Un controller llamado ShopController con una action llamada order Grails lo expone en la URL /app/shop/order
Views en un directorio /views/shop/order Grails usa esas views para la action order del ShopController
Clase Customer en la carpeta domain Grails crea una tabla llamada

###Agile Philosophy Groovy! Código más corto, entendible y tweakeable. Iteración de desarrollo más fluida con reloading de recursos en runtime.

###Rock-solid Foundations Spring y Hibernate. Reliable y battle-tested. Muchísima documentación. Conocimiento previo de alguno no se pierde. Misma filosofía con plugins como Quartz, Lucene y Compass. Lo mismo con SiteMesh.

###Scaffolding and Templating Comandos simples y templates suficientes para aplicaciones básicas o bootsrapeos. Scaffolding genera views y controllers a partir del modelo para poder tener una aplicación funcionando en pocos minutos.

###Java Integration Hay problemas ya solucionados en Java con excelentes implementaciones, entonces por qué reinventar la rueda? Sabemos que un lenguaje con tipado estático es mejor para resolver ciertas tareas, por qué no usarlo? Se pueden usar todos los JARs o .java que se quieran.

###Incredible Community Comunidad muy activa, no solo de Grails sino de las tecnologías que usa. Wikis, mailing list, Twitter, podcasts, YouTube, etc.

###Productivity Ethos “Web apps come and go; zucchinis are forever.”

##Estructura Estructura de App

##Ejercicio

  • Crear la app con el comando grails create-app qotd

  • Moverse al directorio creado con cd qotd

  • Ejecutar la app con grails run-app

  • Abrir un browser y navegar a http://localhost:8080/qotd

  • Detener la app con Ctrl + C, grails stop-app en otra terminal o stop-app en modo interactivo

  • Crear un controller con grails create-controller quote

  • Agregar la action home

def home() {
	render "<h1>Real Programmers do not eat Quiche</h1>"
}
  • Settear home como la default action del controller
static defaultAction = "home"
  • Agregar la action random
def random() {
	def staticAuthor = "Anonymous"
    def staticContent = "Real Programmers don't eat much quiche"
    [ author: staticAuthor, content: staticContent]
}
  • Agregar la view random.gsp para la action random
<html>
	<head>
    	<title>Random Quote</title>
	</head>
	<body>
    	<div id="quote">
	    	<q>${content}</q>
		    <p>${author}</p>
        </div>
	</body>
</html>
  • Modificar el layout y settear un title genérico

  • Crear una domain class con grails create-domain-class book

  • Agregar algunos fields

String title
String genre
String isbn
Date published = new Date()
  • Generar su controller y view con scaffolding con grails generate-all qotd.Book

  • Cambiar a una base de datos en MySQL

development {
	dataSource {
	  pooled = true
	  dbCreate = "create-drop"
	  url = "jdbc:mysql://localhost:3306/qotd"
	  driverClassName = "com.mysql.jdbc.Driver"
	  username = "root"
	  dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
	}
	
	hibernate 
	{
	  cache.use_second_level_cache = false
	  cache.use_query_cache        = false
	  jdbc.batch_size              = 50
	  loggingSql                   = true
	}
}
  • Agregar dependencia al connector de MySQL
dependencies {
	runtime 'mysql:mysql-connector-java:5.1.32'
}
  • Crear una domain class con grails create-domain-class quote

  • Agregar algunos fields

String content
String author
Date created = new Date()
  • Crear un test de integración para la domain class con grails create-integration-test quote

  • Testear el guardado de quotes

def "Saving our first quote to the database"() {
	given: "A brand new quote"
	    def quote = new Quote(author: 'blabla', content: 'blabla')
    when: "The Quote is saved"
    	quote.save()
    then: "It saved successfully and can be found in the database"
    	quote.errors.errorCount == 0
        quote.id != null
        Quote.get(quote.id).author == quote.author
}
  • Agregar constraints a la domain class
static constraints = {
	author nullable: false, blank: false
    content maxSize: 1000, nullable: false, blank: false
}
  • Testear las constraints
def "Trying to save a quote with invalid properties causes an error"() {
    given: "A new quote without author"
        def quote = new Quote(content: 'blabla')
    when: "The Quote is validated"
        quote.validate()
    then: "It is not saved and error information can be obtained"
        quote.hasErrors()
        quote.errors.errorCount != 0
        quote.id == null
        !quote.errors.getFieldError('content')
        quote.errors.getFieldError('author').code == 'nullable'
}
@mathifonseca
Copy link
Author

La solución del Ejercicio está en el repositorio: https://github.com/grailsinthecloud/qotd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment