sábado, 28 de marzo de 2009

Adjuntando archivos en rails

En el proyecto que estoy trabajando ahora, una aplicación para la administración de bienes raíces utilizando rails, me he topado con tener que agregar fotos a mi modelo "propiedad".
No solo necesitaba agregar imágenes, sino generar thumbnails de al menos 2 tamaños distintos.

Por suerte me topé con Paperclip que facilita infinitamente trabajar con archivos dentro de Rails. A continuación les presento un tutorial básico de su instalación y configuración:

Paperclip es un plugin de Rails, se pueden descargar la última versión de acá y extraerla en la carpeta /vendor/plugins de su proyecto. Ahora supongamos que queremos agregar una foto a nuestro modelo Usuario, para ello utilizamos has_attached_file de la siguiente forma:
  class Usuario < ActiveRecord::Base
has_attached_file :foto, :styles => {
:mediana => "300x300>",
:thumb => "100x100>" }
end
Como podemos ver, en el array :styles le pasamos las medidas de nuestros thumbnails, por lo que cuando subamos una foto, Paperclip generará 3 versiones: la original, una mediana de 300x300 y un thumnail de 100x100. Ambas operaciones de re-dimensionamiento mantendrán las proporciones de la imágen. Si se quiere cortar la imagen a redimiensionar hay que especificar el tamaño de esta forma: "100x100#".

Ahora necesitamos crear una migración para agregar los campos necesarios a nuestra tabla usuarios.
class AgregarFotoDeUsuario < ActiveRecord::Migration
def self.up
add_column :usuarios, :foto_file_name, :string
add_column :usuarios, :foto_content_type, :string
add_column :usuarios, :foto_file_size, :integer
add_column :usuarios, :foto_updated_at, :datetime
end

def self.down
remove_column :usuarios, :foto_file_name
remove_column :usuarios, :foto_content_type
remove_column :usuarios, :foto_file_size
remove_column :usuarios, :foto_updated_at
end
end
Corremos las migraciones:
rake db:migrate
El siguiente paso es modificar nuestro form de Usuario para subir una imágen.
<% form_for :usuario, @usuario, :url => usuario_path,
:html => { :multipart => true } do |form| %>
<%= form.file_field :foto %>
<% end %>
No olvidarse de "multipart => true" ya que es lo que permite al form subir la imágen en el post.
Por suerte no tenemos que tocar nuestro controlador.

Para mostrar la foto en las vistas:
  <%= image_tag @usuario.foto.url %> #muestra la original
<%= image_tag @usuario.foto.url(:mediana) %> #muestra la mediana
<%= image_tag @usuario.foto.url(:thumb) %> #muestra el thumb

sábado, 28 de febrero de 2009

Timestamps en Grails

Para clases del dominio, necesitamos a veces utilizar fechas de creación y modificación. En Rails ya vienen los timestamps por defecto en las migraciones. Grails, para no quedarse atrás lo hace bastante sencillo.
Para cualquier clase del dominio que quieras agregarle los timestamps de creación y modificación debes usar los siguientes atributos:

class Usuario{
String nombre
String documento
//demas atributos...
Date dateCreated //fecha de creación
Date lastUpdated //ultima actualización
}

Recuerda que para que no te cree el campo al generar las vistas, debes poner esto en las constraints:


static constraints ={
lastUpdated(display:false)
dateCreated(display:false)
}


Espero que sirva!

lunes, 8 de septiembre de 2008

Grails - Objetos Command

Hay veces que necesitamos mapear propiedades para actualizar una clase del dominio que no necesariamente se corresponden con el mismo, o tenemos interacciones que ni siquiera utilizan una clase. 
Incluso en estos casos nos facilita la tarea las validaciones y data bindings de grails. Para utilizar estas facilidades debemos recurrir a las clases Command.
En el siguiente ejemplo usaremos un objeto Command para cambiar un password en el ámbito de un controlador de Usuario.
El primer paso es crear una clase PasswordCommand (podemos incluso crearla dentro del mismo archivo en donde tenemos nuestro controlador).

class PasswordCommand {
    String password_actual
    String password_nuevo
    String password_confirmacion    

static constraints = {
password_nuevo(blank:false, minSize:6)
}
}

Esa clase es como cualquiera del dominio, podemos definir las costraints que queramos. Luego sólo falta utilizarla en la acción que necesitemos, en este caso en la acción cambiarPassword:

class UsuarioController{
def cambiarPassword = {PasswordCommand cmd ->
if(!cmd.hasErrors()){
//procesar
}
}
}


Al definir así nuestra acción, Grails creará una instancia de PasswordCommand, haciendo binding de las propiedades que vienen en el request.

Como verán no es un trabajo muy complicado y nos ahorra el trabajo de validar "manualmente" esos parámetros que quedan fuera del dominio.

viernes, 1 de agosto de 2008

Exportar a Excel en Grails

En mi último proyecto en Grails, el cliente quería exportar a excel muchas de las consultas que proporcionaba el programa.
Como no encontré mucha información por ahí, les cuento lo que se me ocurrió a mi.
Antes que nada, utilicé JExcelApi para generar los archivos excel. Recuerden que en Grails podemos utilizar cualquier librería Java existente.

Primer paso, colocar el jar (jxl.jar en nuestro caso) de la librería en la carpeta "lib" de nuestro proyecto.
Ya que tenía varios métodos para exportar, decidí crear un servicio en grails que encapsulara a los mismos . Lo único que hay que hacer es agregar los imports correspondientes a las clases que utilicemos para nuestro excel.
import jxl.*;
import jxl.write.*;
Lo que nos queda es implementar nuestros métodos usando JExcelApi (ejemplos en otra ocasión) y llamar al servicio desde nuestro controlador.

Para agregar el servicio a nuestro controlador sólo debemos definir una variable del mismo nombre y será "inyectada" automáticamente a través de Spring. En mi caso el servicio se llamaba Report, entonces

def reportService
Hay que tener en cuenta que a los métodos de reportes les pasé como parámetro el response, así escribimos en el mismo y al cliente le aparecerá el diálogo para bajar un archivo XLS.

en el controlador:
response.setHeader("Content-disposition",
"attachment; filename=Clientes.xls")
response.contentType = "application/vnd.ms-excel"
//"clientes" es una lista de objetos del dominio
reportService.exportClientes(response.outputStream, clientes)

en el reporte:
def workbook = Workbook.createWorkbook(outputStream);
Y eso es todo. Tal vez más adelante ponga algún ejemplo de como utilizar JXL, pero es trivial.

domingo, 6 de julio de 2008

Clocking IT - Project Management

Hace ya casi un mes que estoy utilizando ClockingIT, un sistema muy interesante para los que nos gusta tener organizado nuestros proyectos, tareas y tener un registro de las horas trabajadas.

Lo bueno de esta aplicación es que es GRATIS!, si gratis e incluso los propios creadores se encargan del hosting. Resumiendo un poco lo que nos permite :
  • Manejo de Clientes
  • Manejo de Proyectos
  • Manejo de Hitos
  • Manejo de Tareas
  • Manejo de Usuarios y permisos sobre los proyectos (permite asignar tareas a otros usuarios)
  • Notificaciones (email, rss)
  • Reportes
  • Y si, esta disponible en español
  • muchas más cosas que todavía no utilicé...
ClockingIT fue desarrollado en Rails por dos personas, que querían aprender esta nueva tecnología (y la verdad que les quedó muy bueno).
Si todo esto no los convence, pueden bajar el código fuente, modificarlo a gusto y configurarlo en su propio hosting.

jueves, 22 de mayo de 2008

Comentarios - control de versiones

Me encontré con este artículo que propone un formato bastate interesante para los comentarios en los commits, ya sea Subversion o CVS.
Me pareció interesante ya que suele suceder en los proyectos que debemos hacer un rollback de un cambio, o solucionar un bug y vamos al historial del repositorio ya que muchas veces ese cambio no lo hicimos nosotros.
El formato que se propone ayuda mucho a identificar que se realizó en cada commit.

En el artículo se proponen estos "tags" para agrupar la información del los comentarios:
  • ADDED - descripción de que se agregó
  • CHANGED - descripción de lo que se cambió
  • FIXED - bugs que se corrigieron (se propone poner un link al bug)
  • DELETED - lo que se borró

lunes, 12 de mayo de 2008

Trim sencillo en Javascript

Usando la propiedad prototype, en este caso para la clase String, podemos hacer una función de trim para los Strings.
String.prototype.trim = function() {
return(this.replace(/^\s+/,'').replace(/\s+$/,''));
}
Luego para cualquier String hacemos:
var texto = " He aquí un texto   ";
texto = texto.trim(); //retorna el texto sin espacios delante o detrás