Thinking on hiring me?

Please read

Fernando Guillén

a Freelance Web Developer

cabecera decorativa

software development as an artistic expression

Archive for Agosto, 2008

Sábado, Agosto 30th, 2008

Ruby, sanitizando tus títulos en 2 líneas.

Ayer me acosté super contento, había conseguido escribir una función para sanitizar strings, o como dicen por ahí: crear un SLUG (que todavía no he encontrado la definición exacta).

Si no sabes de que hablo se trata de convertir un “Hola mundo!, qué tal?” en un “hola-mundo-que-tal” para las URLS bonitas y todo eso.

No había sido fácil pues Ruby se lleva mal con los caracteres no-ASCII y el castellano tiene muchos, había que hacer un pequeño malabarismo con la gema Unicode.

Al final mi función se veía así:

require 'unicode'
def to_slug( sentence, length = 64 )
  return if sentence.blank?
 
  wrong = ['á','é','í','ó','ú','ä','ë','ï','ö','ü','à','è','ì','ò','ù','ñ','ç','º','ª','_']
  right = ['a','e','i','o','u','a','e','i','o','u','a','e','i','o','u','n','s','o','a','-']
 
  sentence = sentence[0..length-1]
  sentence = Unicode.downcase( sentence )
 
  for i in 0..wrong.size-1
    sentence.gsub!( wrong[i], right[i] )
  end
 
  sentence.gsub!( /[^a-z0-9-]/, '-' ) # not letters of numbers
  sentence.gsub!( /-{2,}/, '-' )      # 2 or more '-' together becoming 1 '-'
  sentence.gsub!( /^-|-$/, '' ) unless sentence.size == 1 # '-' at begging or at end
  sentence
end

Estaba super orgulloso hasta que me despierto por la mañana y cambiando la pregunta a Google me encuentro con un… ‘inombrable’ que me hace esto:

require 'unicode'
def to_slug
  str = Unicode.normalize_KD(self).gsub(/[^\x00-\x7F]/n,'')
  str = str.gsub(/\W+/, '-').gsub(/^-+/,'').gsub(/-+$/,'').downcase
end

Exactamente (casi) lo que yo tenía pero en 2 líneas.

¡Así es Ruby!

Al final he hecho algún cambio y cogido lo bueno de uno y de otro y le he añadido soporte para STOPWORDS:

STOPWORDS = [
  'de','a','que','no','tiene','en','para',
  'por','le','la','lo','las','los','el',
  'una','un'
]
 
def to_slug( length = 64, drop_stopwords = false )
  return "" if self.length == 0
 
  str = Unicode.normalize_KD(self).gsub(/[^\x00-\x7F]/n,'').downcase
 
  # stopwords
  if drop_stopwords
    STOPWORDS.each do |stopword|
      str.gsub!( /\s#{stopword}\s|^#{stopword}\s/, ' ' )
    end
  end
 
  str = str.gsub(/[^A-Za-z0-9]/, '-').gsub(/^-+/,'').gsub(/-+$/,'').downcase
  str = str[0..length-1]
end

Por su puesto que se recomienda completar la lista de STOPWORDS con las que quieras.

Jueves, Agosto 28th, 2008

Ruby, el ‘print’ necesita que hagas un flush del $stdout

No conseguía hacer un indicador progresivo de un proceso, o lo que es lo mismo: el típtico ‘punto… punto… punto…‘ para indicar que el proceso sigue en marcha.

Si utilizada puts o p se me generaba un salto de carro al final de cada ‘punto‘. Y si utilizaba ‘print‘ simplemente no salía nada hasta que cancelaba el proceso… o terminaba.

Estaba claro que ‘print‘ estaba insertando los ‘puntos‘ en un bufer y había que ‘flusearlo‘.

La solución:

print '.'; $stdout.flush

Mira aquí y aquí.

Jueves, Agosto 28th, 2008

Ruby on Rails, no se me está inicializando el estado de las tablas al ejecutar un test

Estaba yo haciendo unos testecitos y veo que no se me estaban borrando los datos de la base de datos al ejecutar cada test lo cual me estaba generando unos poltergeist horribles.

Un comportamiento de Rails en el que confiaba como era este: “La base de datos vuelve al estado original en cada test“, me estaba traicionando.

Bueno el problema era que como mis tests no usaban fixturas no las estaba cargando y resulta que es la carga de las fixturas lo que borra la bd y no la propia suite de tests.

Solución:

fixtures :mimodelos

Aunque no use las fixturas es lo que he tenido que hacer para que la tabla se borrase con cada test.

¡Qué cosas!

Miércoles, Agosto 27th, 2008

Ruby, extraer la parte html del body de un email con parte html y part texto plano

Normalmente cuando se escribe un email en formato enriquecido el propio cliente de email se encarga de generar dos partes dentro del email, una con el texto en formato html (enriquecido) y otra en formato texto plano por si el cliente de correo con el que finalmente el destinatario lo abra así lo quiere.

Bien, para una aplicación en la que estoy trabajando se requiere que dado un email con varias partes (html y texto plano) pueda extraer sólo la parte html.

No he encontrado nada en la clase TMail::Mail de Ruby que me ofrezca esta funcionalidad.

No parece difícil en un principio, pero en realidad si profundizas un poco si que se vuelve lioso. Si cogemos el body del Mail lo tenemos todo junto y no sabemos donde cortar, ni siquiera si es requerido cortar. Si empezamos a recorrer las partes del Mail podemos empezar a rastrear los content_type de cada una pero esto puede resultar engañoso pues la parte con el body en formato enriquecido tiene el mismo content_type que un fichero html adjunto en el email.

Al final lo que me ha quedado es este método:

def body_html
  result = nil
  if multipart?
    parts.each do |part|
      if part.multipart?
        part.parts.each do |part2|
          result = part2.unquoted_body if part2.content_type =~ /html/i
        end
      elsif !attachment?(part)
        result = part.unquoted_body if part.content_type =~ /html/i
      end
    end
  else
    result = unquoted_body if content_type =~ /html/i
  end
  result
end

Es un método que extiende la clase TMail::Mail para ofrecer el método .body_html que devuelve la parte html o nil si no hay ninguna parte de texto enriquecido.

Puede parecer liosa pero en realidad está inspirada en el método .body de la propia clase TMail::Mail.

Podéis descargaros el parchecito de TMail::Mail y hacer un require del mismo, o también podéis mirar directamente el repositorio donde lo he subido junto con unos pocos tests.

Cualquier comentario es bienvenido.

Miércoles, Agosto 27th, 2008

Ruby, uso de caracteres no ASCII en la consola IRB del Mac OS X

Mis versiones:

  • Mac OS X 10.5.4
  • Ruby 1.8.6 patchlevel 114
  • Rails 2.1.0

Tengo problemas para introducir caracteres no ASCII ( caracteres especiales, acentos y ñs ) en la consola IRB de Ruby así como también en la consola script/console de Rails.

Gracias a las lista ror-es lo he podido solucionar.

Resumo aquí a mi manera el post con la solución:

Instalamos la versión universal de la librería readline mediante MacPorts:

$ sudo port install readline +universal

Si te dá error de:

-bash: port: command not found

Asegúrate que tienes instalados los MacPorts y que tienes esto en tu .bash_profile:

export PATH=$PATH:/opt/local/bin
export MANPATH=$MANPATH:/opt/local/share/man
export INFOPATH=$INFOPATH:/opt/local/share/info

Instalamos la extesión Ruby para readline. Vigila la versión que te bajas, debe coincidir con tu versión de Ruby exactamente:

$ ruby --version
ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0]

v1_8_6_114

$ cd /tmp
$ svn co http://svn.ruby-lang.org/repos/ruby/tags/v1_8_6_114/ext/readline/ readline

Aplicamos un parchecito:

$ curl http://pastie.textmate.org/pastes/168767/download | patch readline/extconf.rb

Y compilamos, necesitarás tener instaladas las OS X developer tools:

$ cd readline
$ ruby extconf.rb
$ make
$ sudo make install

Si el script/console te sigue dando problemas asegúrate de tener bien la $KCODE:

$ script/console
Loading development environment (Rails 2.1.0)
>> puts $KCODE
UTF8
=> nil

Gracias de nuevo a Daniel Rodriguez Troitiño por la solución.

Viernes, Agosto 22nd, 2008

¡Qué joven era! o mi camino con Rails.

Aclaración: En este texto repito mucho la palabra Rails, todo el mundo entiende que me refiero a Ruby on Rails. Pero creo que en muchos de los contextos debería haber puesto Ruby. Para mí Rails no sería nada sin Ruby y Ruby no sería nada sin un framework como Rails.. pero Rails es más suplantable que Ruby.

He estado viendo una de las charlas de las Conferencias Rails 2007.

Concretamente la de Fernando Blat sobre caché en Rails. Estoy intentando integrar esto de las cachés en un proyectillo basado en Rails que estoy haciendo.

La paradoja es la siguiente: resulta que sale uno haciendo una pregunta (minutos 41:40 al 43:00) que justamente me ha surgido a mí mientras videaba la charla. Resulta que el que hace la pregunta soy yo, resulta también que el proyecto en el que estoy trabajando lo hago bajo la supervisión del mismo Fernando Blat y es a quién se la iba a preguntar en persona. Resulta que no me acordaba de nada de esta charla. Resulta que no tenía ni idea de Rails en ese momento y que justamente ahí y entonces es cuando estaba pasando la etapa de la ironía y del rechazo para pasar a la de la aceptación.

Han pasado exactamente 9 meses de esa charla y las cosas han cambiado realmente mucho.

Conferencias Rails 2007

Fuí a las Conferencias Rails 2007 con una actitud completamente escéptica. Ya había oído hablar de Rails a los más freakies de mi cuadrilla, y también al más experimental de mis socios, pero había obviado sus comentarios con bastante incredulidad, yo soy una vieja mole de Java y estaba encantado con ser así.

Normalmente actúo con esta actitud ante la presencia de cualquier nueva tecnología que me presentan, no me gusta ser pionero en experimentar, me gusta vigilar desde la costa hasta ver si el barco sigue navegando cuando el viento amaina.

Voy en la cola de la comunidad, un paso por detrás de la cresta. Esto puede que me haga retrasarme un poco pero conozco el esfuerzo que requiere adquirir experiencia en cualquier tecnología, y lo que es peor, el esfuerzo que requiere dejarla cuando ha sido una decisión desacertada, por lo que cuando pongo algo en el punto de mira lo hago con mucha energía ahorrada.

Si me hubiera dejado llevar por todo canto de sirena que he escuchado me habría perdido en el baile eterno de ruidos como EJBs o Google Web Toolkit.

Durante las Conferencias Rails 2007 yo era un convencido de Java, no creía que nada de lo que oyera ahí fuera a convencerme, tengo la experiencia de que este tipo de conferencias endogámicas suelen ser un circuito de palmaditas en las propias espaldas vacías de contenido.

El primer día lo pasé discutiendo con la gente que se me acercaba, incluso con los conferenciantes ( Arquitectura hardware en Rails minutos 46:00 al 50:45, Tomatine minutos 18:30 al 20:30, Mtv.es minutos 26:20 al 28:00, y alguna más que no quedá grabada.. menos mal :) ) , expresando mi escepticismo hacia el cúmulo de bondades que este semi-nuevo framework estaba trayendo al mundo del desarrollo de software. Lo llaman la fase de la negación. Ya había pasado la fase de la ridiculización.

El segundo día llevaba un cabreo de la leche. No podía ser, no era cierto. No quería cambiar, quería que Java siguiera siendo lo mejor. Pero dentro de mí empezaba a solidificarse una revelación: Rails era mejor, no para el desarrollo web, sino para mí.

Era la primera vez que oía tantas veces repetida como feature de un framework: “la búsqueda de la felicidad del programador“. Me estaban hablando a mí, eso es lo que he buscado siempre en mi profesión: la felicidad. Entiéndase la felicidad del programador no como currar poco y cobrar mucho sino como ‘resolver‘ una necesidad de una manera elegante y ágil.

Me entró un temblor débil, dejó de ser desagradable. Recuperé el entusiasmo que cíclicamente me viene: Cuando hice mi primer FOR en el BASIC del MSX, cuando moví mi primer Sprite, cuando parcheé mi primera interrupción de teclado, cuando hablé con una bombilla vía puerto paralelo, cuando hice mi primera función C, cuando accedí por primera vez directamente a la memoria de vídeo, cuando inserté mi primer registro en una base de datos, cuando envié mi primer mensaje entre dos sockets, cuando hice mi primera web dinámica, … creo que a partir de entonces lo había perdido, todo se había vuelto pesado y costoso.

Rails había venido para rescatarme.

Las conferencias acabaron pero del poso en el estómago surgió una inquietud indomable.

Dejo Constela

Todo se había juntado, a mi agotamiento como desarrollador se sumaba el peso y responsabilidad de ser socio de una empresa que había empezado ha crecer y a comer recursos y presupuesto con avidez.

En Constela, con la compañía de mis socios Jesús y Miguel y del resto de equipo que juntamos, me hice fuerte, me hice duro, conseguí una experiencia que solo se consigue con la lucha. Les debo mucho.

Pero me sentía pesado, mis movimientos se habían vuelto costosos, el barco era fuerte pero su timón era muy duro y me bajé. Me dejaron una barca y empecé a navegar, remando, despacito, cantando.

Me pongo a comprar libros Rails como un loco

El entusiasmo había vuelto, la avidez autodidacta solicitaba información, ahora tengo casi todo lo recomendable traducido al castellano y casi todo lo imprescindible sin traducir.

Devoro información, todo es demasiado diferente, el click en mi cabeza tardó en llegar y todavía oigo su eco por lo reciente que ha sido.

Entro en la lista ror-es

La lista de desarrolladores de Rails en castellano, una comunidad muy pequeña pero inspiradoramente entusiasta y animada. Duramente moderada por @mort a quien he temido e incluso odiado en mi primera etapa, ahora casi-superada.

Hago la tienda de Hola Por Qué

Mi primer Hola Mundo en Rails no es una paginita con un mensaje insulso, es una tienda online :)

Muy pocas líneas de código picadas con el método de prueba y error, sin haber conseguido todavía hacerme con la sintaxis de Ruby ni el intríngulis de Rails, escribía instrucciones y declaraba variables al tanteo hasta que ningún Sintax Error ni nigún Error 500 aparecía.

Todo montado sobre sólo 2 tablas de base de datos.

Fichado por La Coctelera

Para mí La Coctelera ha sido, desde que conozco Rails, como el buque insignia español de este framework.

Escribo a Álvaro para comunicarle mi deseo de entrar a formar parte de un equipo con experiencia y entusiasmo como el suyo.

A los pocos días me encuentro con una seudo-entrevista de trabajo en un vagón de metro de la línea 1 con Álvaro y Fernando Blat.

Yo no llevo nada para enseñarles sólo les transmito mi entusiasmo y mi seguridad de que simplemente “se me dá bien esto del desarrollo web”. (Bueno, igual mi experiencia como responsable de tecnología en Constela y jefe de proyecto en el desarrollo de Kroonos fueron una buena carta de presentación).

Tienen entre manos un proyectillo que parece pensado para mí y me pongo manos a la obra. Y aún hoy sigo dando guerra por sus oficinas.

La experiencia de trabajar con un equipo de desarrollo ágil como el que tienen aquí en La Coctelera y The Cocktail en general, además de estar bajo la continua supervisión y apoyo de un joven gurú de nuestros tiempos como es Fernando Blat me está haciendo recuperar a grandes zancadas el retraso provocado por mi, aún valorado y mantenido, escepticismo.

Voy al Euruko

Y cojo y me voy a Praga, al Euruko 2008. Unas conferencias temáticas sobre Ruby. No disfruto tanto dentro como fuera de las conferencias.

Afuera me acoge con un pequeño grupo de raileros que también habían venido desde España, casi todos gurús de Rails y todos un encanto de personas.

Son las primeras conferencias de programación en las que se mezclan de manera perfecta las experiencias freakies con las amorosas.

La foto con el creador de Ruby

Y subiendo escalas en mi incipiente carrera como gruppy de Ruby aquí me tenéis, en una foto de pésima calidad, con el creador de Ruby Yukihiro ‘Matz’ Matsumoto y uno de los gurús al que llaman Dr Nic.

Foto con Dr Nic y Yukihiro ‘Matz’ Matsumoto

Red de amigos raileros y madrid-rb

El Euruko, las charlas, las comilonas y las risas crean pequeños vínculos que se comienzan a reafirmar con el reempuje de la comunidad Ruby de Madrid, del que soy testigo.

El último jueves de cada mes es la kdd oficial del grupo de Ruby de Madrid y aunque esta comunidad sea mucho más pequeña el karma de este lenguaje hace que las kdds sean mucho más populares que las de Java que solía convocar con la gente de Java-Madrid hace unos años.

Ahora ya conozco en persona a prácticamente la totalidad de los conferenciantes de esa mítica Conferencias Rails 2007 :)

Miembro fundador de rsug

Y me encuentro firmando el acta como uno de los socios fundadores de la asociación Ruby Spanish User Group, que aunque ahora no tenga los conocimientos ni experiencia suficiente espero aportar/devolver algo de lo que siempre tanto recibo a la comunidad.

Participo en el 2º concurso de programación de OpenMovilForum

E hinchado de orgullo por mis rápidos progresos me incribo al concurso de programación del OpenMovilForum con unas expectativas desorbitadas de llevarme el primer premio.

Presento no 1 sino 2 proyectos desarrollados en unas 3 semanas. Algo imposible de imaginar para mí hace pocos meses.

El resultado: me como los mocos. Pero empiezo a notar la soltura, empiezo a sentirme ágil.

Lluvia de ofertas de trabajo

Aunque no todas han acabado en acuerdo, sí que noto que mi perfil empieza a ser apetitoso.

Los principales escollos que veo es que el cliente sigue pensando que esto del desarrollo web es una baratija o que un freelance es intrínsecamente mucha más barato que una empresa.

En cualquier caso me siento cómodo y sé que cada vez me siento más capacitado para dar a los clientes lo que de verdad quieren: opinión, una persona resolutiva, prototipos rápidos y desarrollo iterativo.

Me compro un mac

¿Es este un paso que tiene que ver con mi incursión en Rails?…

Indudablemente sí, contagiado por la fiebre maquera que afecta a esta comunidad. Pero sobre todo tiene que ver con la búsqueda, mucho más antigua, de la agilidad.

¿Soy más feliz ahora?

Sí.

¿Será por Rails?, ¿por volver al mundo freelance?, ¿por mi nuevo Mac?… ¿por el amor?.. qué más da!

Jueves, Agosto 14th, 2008

Seudo soporte PNGs transparentes en IE6

Disclaimer: soy desarrollador web pero del lado oscuro: el de la parte servidor y, aunque me toca tocar de todo, el CSS, y el diseño web en general, no son mi especialidad. Así que si ves alguna página de algún maquetador especializado en la que se contradice algo de lo aquí digo hazle caso a él.

La pesadilla del maquetador web tiene nombre y éste es Internet Explorer 6. El Navegador más uebón de todos los navegadores. Y pese a que tiene más de 7 años, que está intentando ganar el récord a software con más agujeros de seguridad y que la versión 7 hace 2 años que está disponible, aún sigue siendo el navegador más usado… después de FireFox ;..)

Una de las mayores cerraduras de esfinter que nos encontramos al probar nuestra flamante web en un IE6 es que éste no soporta PNGs transparentes. :O

Bueno, sí que los muestra, pero en vez de la resultona transparencia aparece un desagradable tonillo gris con transparencia nula.

Existen muchos sitios donde te explican como hacer para que el IE6 soporte los PNGs transparentes.. pero la cruda realidad es que no hay manera, olvídate. Cambia todos los PNGs transparentes por PNGs no transparentes o JPGs o incluso GIFFs, pero no te metas en el lío de intentar conseguir que el IE6 te lea bien los PNGs transparentes..

Lo puedes hacer sólo para el IE6 con el hack de los comentarios condicionales para IE y cargando CSSs específicos para este navegador.

Si después de lo dicho te empecinas en hacerlo, allá tú, y aquí tienes la manera de acercarte lo más posible a conseguirlo.

Existen 2 hacks diferentes que tenemos que usar dependiendo de si el PNG transparente está incluido en la página mediante un <img> o mediante un background-image.

PNG transparente metido en una <img>

Éste es el más fácil y el soporte es casi total. A mi no me ha dado ningún problema.

Es muy fácil porque se utiliza un javascript que han hecho una gente muy simpática llamado pngfix.js.

Es una mala bestia de script en 30 líneas que selecciona todas los elementos <img> que contienen un PNG y los sustituye por elementos <span> con una imagen de fondo que es la misma PNG. Usa para ello el hack del IE6 para PNG en background-image que vemos a hora a continuación.

Para activarlo no hay más que descargarse el pngfix.js y llamarlo desde el HTML con:

<!--[if lt IE 7]>
  <script defer type="text/javascript" src="pngfix.js"></script>
<![endif]-->

Así sólo se activará si el navegador detectado es una versión anterior al IE7.

PNG transparente como background-image

Éste funciona siempre y cuando no queramos usar el background-repeat y/o el background-position. Si queremos usar estos atributos estamos jodidos y volvemos al punto del principio: olvídate.

Es decir sólo funciona en caso de que la imagen de fondo no queramos que se repita o que se coloque en una posición que no sea la 0,0.

El truco, o hack, fué ofrecido por la propia gente de IE6 que, diéndose cuenta de la carencia de su motor de renderizado, rebuscaron y rebuscaron y dieron con una posible solución: usar un filtro propietario llamado AlphaImageLoader que es capaz de cargar PNGs transparentes vía CSS.

Está claro que no vamos a usar este truco (chapuza) en todos los navegadores así que lo que hacemos en un CSS que sobrescriba los valores normales y los sustituya por los que necesita el IE6.

Así que generamos un CSS que sólo lo lea el IE6 y lo cargamos desde el html tal que así:

<!--[if IE 6]>
  <style type="text/css" media="all">@import "/stylesheets/ie6.css"</style>
<![endif]-->

En este CSS vamos a hacer todos los ajuste que el IE6 necesite. Entre ellos el del AlphaImageLoader.

Cogemos todos los elementos CSS que contengan un background-image y ponemos cosas coma ésta en nuestro ie6.css:

.clase_css{
  background-image: none;
  filter: none !important;
  filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/imgs/imagen.png");
}
#id_css{
  background-image: none;
  filter: none !important;
  filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/imgs/imagen.png");
}

Y repito: si requieres que la imagen se repita estás perdido, lo máximo que puedes hacer es que la imagen se estire con:

#id_css{
  background-image: none;
  filter: none !important;
  filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/imgs/imagen.png", sizingMethod="scale" );
}

O si la imagen es más grande que el elemento que la contiene puedes cortarla:

#id_css{
  background-image: none;
  filter: none !important;
  filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/imgs/imagen.png", sizingMethod="crop" );
}
Los links dejan de funcionar

O cuando parece que hay luz al final del tunel viene otro tren y nos aplasta.

Con el truco del AlphaImageLoader resulta que determinados links dejan de funcionar. También hay <p> que ya no se pueden seleccionar o formularios que no se dejan rellenar.

Ni el problema ni la solución está muy clara pero el workarround que se propone por ahí es buscar los componentes que fallan y ponerles un

position: relative

Con esto se suele arreglar bastantes cosas:

a {
  position: relative;
}

Para las demás deberá ir haciendo pruebas.

Los elementos no se estiran para contener su elementos hijos

Otro tren que pasa es que puede que los divs no crezcan hasta soportar todos los elementos que contienen, en caso de que ocurra esto hay que jugar con:

height: 100%;

y

height: auto !important;

Actualizado:

Parece que hay un script que intenta solucionar todos estos problemas el solito, se llama SuperSleight. Lo he probado pero ya tenía todo el tinglado montado y me funcionaba un poco mejor.

PD: hazte de la campaña SaveTheDevelopers o a la de EndIE6 y activa el script que ofrecen en tus páginas para incitar a que la gente que sigue usando IE6 se actualice .. porfavor¡¡

Lunes, Agosto 11th, 2008

Ruby on Rails: definir el tamaño de un índice MySQL en las migraciones

Revisando el log de tus queries te puedes encontrar que si estás buscando registros por un campo VARCHAR te salte un warning de “long key length“.

Esto es porque el índice que has puesto en este campo VARCHAR es muy grande, aunque MySQL soporta índices de hasta 1000 bytes si son muy grandes pueden ralentizar las búsquedas.

La solución está en limitar el tamaño del índice a un número bastante pequeño.

En MySQL esto se indica así:

ALTER TABLE mi_tabla ADD INDEX ( campo_del_indice(4) )

ó también:

CREATE  INDEX `nombre_del_indice` ON mi_tabla (`campo_del_indice`(4))

El problema es que si estamos usando ‘migrations‘ de Rails y queremos ser puristas nos encontramos con que la sintaxis estándar de las migraciones de Rails no soporta el campo ‘longitud’.

Como bien dice Jaime Iniesta existe un parche que da soporte a las migraciones para admitir el campo ‘length’.

Yo sin embargo he preferido no tocar el código de mis gemas y meter este fichero (rails_migraions_hack.rb) en el ‘/lib‘ de mi aplicación:

module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module SchemaStatements
      def add_index(table_name, column_name, options = {})
        column_names = Array(column_name)
        index_name   = index_name(table_name, :column => column_names)
 
        if Hash === options # legacy support, since this param was a string
          index_type = options[:unique] ? "UNIQUE" : ""
          index_name = options[:name] || index_name
          index_length = options[:length] ? "(#{options[:length]})" : nil # only mysql
        else
          index_type = options
        end
        quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
        # execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})"
        sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{table_name} (#{quoted_column_names}#{index_length})"
        p "SQL: #{sql}"
        execute sql
      end
    end
  end
end

Y cargarlo con un:

require 'rails_migrations_hack'

En mi environment.rb.

Funciona perfectamente y vemos como saca por pantalla las querys de las creaciones de índices con cosas como esta:

"SQL: CREATE  INDEX `idx_forums_forums_nicetitle` ON forums_forums (`nicetitle`(4))"

Es interesante consultar toda la discusión en la lista de ror-es.

Actualizado (2008-08-13):

Al parecer no estan cubiertas todas las posibilidades.

En el caso de estar creando un índice compuesto el atributo length se lo asigna al último campo y esto puede no ser lo adecuado:

add_index :tabla, [:campo1, :campo2], :name => 'idx_tabla1', :length => '10'

lo que intenta es hacer:

CREATE  INDEX `idx_tabla1` ON tabla (`campo1`, `campo2`(10))

Si el campo varchar que queremos limitar es el primero la hemos cagado..

Habría que intentar modificar la sintaxis del length para que coja algo como esto:

add_index :tabla, [:campo1, :campo2], :name => 'idx_tabla1', :length => { :campo1 => '10' }
Lunes, Agosto 11th, 2008

Ruby, script generador de script javascript para precarga de imágenes en tu html

El truco más sencillo para precargar las imágenes de tu web y así no ver el horrible efecto de mouse-over hueco es hacer un script javascript como este:

img1 = new Image();
img1.src="imagen.jpg";

Esto invocará la imagen y el navegador, sino es muy tonto, la dejará en la caché para cuando verdaderamente la necesite.

Bueno, pues es lo que quiero hacer para una web que tiene un montón de background-image definidos en su css.

Para ello me he hecho un script en ruby que me busca todas las imágenes en todos los css y me genera un script de javascript con todo el rollito de los preload.

class Preloator
  def self.generate_script( css_directory )
    # take all .css on directory
    css_file_names = []
    Dir.foreach( css_directory ) do |file|
      if file =~ /.*\.css$/
        css_file_names << css_directory + '/' + file
      end
    end
 
    # take all the images by looking at 'url'
    image_names = []
    css_file_names.each do |file_name|
      self.grep( 'url', file_name ).each do |line|
        image_names << line.scan( /.*\((.*)\)/ ).flatten.first
      end
    end
 
    # generate the script
    script = "<script>\n"
    image_names.each_with_index do |image_name, index|
      script += "    img#{index} = new Image();\n"
      script += "    img#{index}.src = \"#{image_name}\";\n"
    end
    script += "</script>"
  end
 
  def self.grep( pattern, filename )
    matches = []
    regexp = Regexp.new( pattern )
    File.open(filename) do |file|
      file.each do |line|
        matches << "#{filename} #{file.lineno.to_s}: #{line}" if regexp.match(line)
      end
    end
    matches
  end
end
 
puts Preloator.generate_script( ARGV[0] )

Esto genera una salida como esta:

$ ruby etc/preloator.rb public/stylesheets/
<script>
img0 = new Image();
img0.src="/imgs/fondo.jpg";
img1 = new Image();
img1.src="/imgs/fondo_carpeta.png";
img2 = new Image();
img2.src="/imgs/blog_sombra_abajo.png";
img3 = new Image();
</script>;

Seguramente quieras mejorarlo un poquito: meterlo en un .js o invocarlo cuando el document.load.

El script ahorra trabajo si, como en mi caso, tienes más de 20 imágenes en el css.. y escribir el javascript a mano sería un coñazo.

Viernes, Agosto 8th, 2008

Pesadilla futurista.

Hoy he soñado que todo lo que hacemos se consideraba consumo de recursos de algún extraño servidor.

Es decir, que todas nuestras acciones y movimientos tenían un coste proporcional a la actividad. Mover los brazos airosamente o hacer esfuerzos mentales era más costoso que permanecer sentado con la mente en blanco.

Me he despertado con una gran ansiedad, me daba cuenta que al madrugar estaba ya consumiendo parte de mi limitado ‘ancho de banda‘.

¿Qué ocurriría si me quedaba sin espacio?

a Freelance Web Developer is proudly powered by WordPress
Entries (RSS) and Comments (RSS).

Creative Commons License
Fernando Guillen's blog by Fernando Guillen is licensed under a Creative Commons Attribution-NoDerivs 3.0 Unported License.