Trabe ya no escribe aquí. Puedes encontrarnos en nuestra publicación en Medium: medium.com/trabe.

4Trabes Historias de una empresa en 100 metros cuadrados

El blog de Trabe Soluciones

Extensiones al core de Ruby, pequeños pedazos de código que harán tu vida más sencilla. Hoy Enumerable.pluck y Enumerable.invoke

| | Comentarios

En Trabe Soluciones vamos mejorando las librerías que utilizamos para desarrollar con Rails aplicación a aplicación. Puede decirse que somos como una esponja que va cogiendo buenas ideas de aquí y de allá. Hoy vamos a hablar de una par de extensiones al core de Ruby que utilizamos,

Primero el código:

1
2
3
4
5
6
7
8
module Enumerable
  def invoke(method_name)
    self.each { |o| o.send(method_name) }
  end
  def pluck(method_name)
    self.collect { |o| o.send(method_name) }
  end
end

Cómo podeís apreciar son unas sencillas funciones que solucionan dos tareas más que habituales cuando trabajamos con colecciones: invoke que invoca un método de cada elemento de un Enumerable y pluck que recolecta el resultado de invocar un método concreto sobre cada elemento de un Enumerable. Vamos, que abrevian dos construcciones típicas del lenguaje. Las hemos definido en el módulo Enumerable y no en la clase Array directamente para poder utilizarlas con cualquier clase que incluya este módulo (Array por ejemplo).

La inspiración de estas funciones se la debemos a Prototype, la famosa librería Javascript, que curiosamente se inspira a su vez en ruby:

Most of Prototype’s idioms are influenced by Ruby, and those that have no analog in Ruby defer to existing or emerging web standards

Para terminar un ejemplo autoexplicativo de su utilidad.

1
2
3
4
5
6
7
8
9
# ANTES
def find_by_object_keys(objects)
  find(:conditions => { :key => objects.collect { |o| o.key} }
end

# DESPUES
def find_by_object_keys(objects)
  find(:conditions => { :key => objects.pluck(:key) }
end

Ejercicio para lectores avispados: Ahora sólo tenéis que modificar las funciones para que acepten parámetros para el método invocado. Seguramente lo necesitéis en algún momento.

Rails plugins (2): Annotate Models. Documenta tus modelos ActiveRecord automáticamente

| | Comentarios

El plugin que recomendamos hoy es annotate_models. Esta pequeña extensión ni modifica ni añade comportamiento a nuestras aplicaciones Rails y tampoco nos evita escribir código. No obstante, no debemos despreciar su valiosa ayuda.

annotate models añade una simpática tarea annotate_models al rakefile del proyecto que se ocupa de añadir al comienzo de los ficheros .rb que contienen modelos ActiveRecord un comentario con la información del schema. Esto es, nos anota los modelos con los atributos de la tabla de base de datos asociada al modelo. Veamos una anotación real como ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# == Schema Information
# Schema version: 34
# Annotated on: Wed Oct 10 10:38:58 +0200 2007
#
# Table name: brands
#
#  id         :integer(11)   not null, primary key
#  name_es    :string(255)   
#  name_en    :string(255)   
#  created_at :datetime      not null
#  updated_at :datetime      not null
#  image      :string(255)   
#  complete   :boolean(1)    
#  url        :string(255)
#  margin     :integer(11)   
#

Pequeño pero matón. Una gran ayuda mientras el soporte de los IDE de desarrollo como Netbeans o RadRails no mejore y autocompleten como Dios manda.

Sólo dos pegas (pequeñas, sí, pero ahi están). La primera: siempre anota los modelos, aun cuando no ha cambiado el esquema. Si trabajamos con un control de versiones (porque trabajamos con control de versiones ¿no?) el histórico de revisiones queda un pelín falseado, porque los ficheros han cambiado (esa línea Annotated on maldita), aunque no hayamos modificado el código.

La segunda: sólo anota los modelos de la carpeta model, cuando lo óptimo es que buscase por toda la carpeta del proyecto buscando subclases de ActiveRecord::Base. Si tenéis modelos en otra carpeta tendréis que modifcar el código fuente del plugin (que nadie se asuste, es bastante sencillo).

Resumiendo: anotad vuestros modelos

Pretty URLs mediante reescritura en aplicaciones JEE (J2EE) sin depender de Apache

| | Comentarios

Este es uno de esos artículos “de propósito específico”. Supongo que los que trabajen en entornos “con mucha burocracia” entenderán mejor por qué no siempre es posible tocar el apache. La idea de este post es ver como podemos tener una funcionalidad decente de reescritura de URLs directamente en el contenedor de aplicaciones.

La pieza clave para conseguir nuestro objetivo es UrlRewriteFilter, que como sus propios autores proclaman “Es un filtro basado en mod_rewrite válido para cualquier contenedor estándar de aplicaciones JEE que permite reescribir URLs antes de que lleguen a nuestro código”. Y además funciona.

El filtro es muy sencillo de instalar, tan solo son necesarios unos pocos pasos muy sencillos:

  • Guardar el jar en el lib de nuestra aplicación.
  • Modificar el web.xml para que haga uso del filtro:

1
2
3
4
5
6
7
8
9
10
11
12
13
<filter>
  <filter-name>UrlRewriteFilter</filter-name>
  <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
  <init-param>
    <param-name>logLevel</param-name>
    <param-value>WARN</param-value>
  </init-param>
</filter>

<filter-mapping>
  <filter-name>UrlRewriteFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

  • Incorporar en el WEB-INF de nuestra aplicación un fichero urlrewrite.xml, que contendrá las reglas para las reescrituras

Una vez realizados estos pasos solo nos queda escribir las reglas que consideremos necesarias en nuestro caso. El fichero urlrewrite.xml de ejemplo incluye nociones básicas al respecto. A modo de ilustración, para convertir una URL como /searchPage.do?term=casco&locale=es&make=honda en algo como /es/honda/que-contengan/casco, necesitaríamos una regla como la siguiente:

1
2
3
4
<rule>
  <from>/([a-z]+)/([a-zA-Z0-9]+)/que-contengan/(.*)</from>
  <to>/searchPage.do?term=$3&amp;locale=$1&amp;make=$2</to>
</rule>

Con estos sencillos pasos ya tenemos un soporte decente para construir URLs bonitas en aplicaciones Java, sin tener que hacerlo todo “a mano” ni depender del Apache.