10.lines do: Helpers bajo demanda en Rails

01.03.2010 0

Dentro de los objetivos en uno de nuestros desarrollos en Rails está el tener cuantas más vías mejor a la hora de personalizar la aplicación de cara al cliente. En una de esas últimas incursiones en la carga dinámica para cada cliente estuvimos jugando con el tema de que pudieran tener helpers propios.

Imaginemos que dentro de config/preinitializer.rb tenemos algo como esto:

NUESTRO_CLIENTE = 'foobar'

Podemos crear un fichero llamado config/initializers/helper_loader.rb (el nombre es un poco lo de menos), que contenga lo siguiente:

helper_load_path = File.join(RAILS_ROOT, 'app', 'customizations', NUESTRO_CLIENTE, 'helpers')
ActiveSupport::Dependencies.load_paths << helper_load_path

Por último, creamos un fichero llamado app/customizations/foobar/helpers/foobar_helper.rb parecido al siguiente:

module FoobarHelper
  def nuestro_metodo
    # lo que sea
  end
end

Ya solo nos quedaría meter en nuestro app/controllers/application_controller.rb la siguiente línea:

helper Module.const_get("#{NUESTRO_CLIENTE.titleize}Helper")

Con esto ya tendríamos disponible el helper nuestro_metodo solo en aquellas instancias en las que NUESTRO_CLIENTE fuese foobar y no en el resto. O también nos podría servir para poder definir en varias instancias de manera completamente distinta nuestro_metodo (por ejemplo, definir un ad_tag_helper que para un cliente estuviese optimizada para SmartAdServer, para otro con OpenX, para otro con Google Adsense…).

Las posibilidades que nos brinda estas pocas líneas son infinitas :)

Aniversarios varios

25.01.2010 4

A lo largo de este mes se cumplen años de varios acontecimientos que cambiaron de forma importante aspectos de mi vida:

  • Hace un par de semanas se cumplió el primer año de carnet de conducir. No he logrado la meta que me había propuesto de hacer 10.000 kilómetros durante ese primer año pero no me he quedado muy lejos. Buena parte de los viajes que he hecho por mi cuenta han servido para poder salir con la cámara y fotografiar rincones de esta tierra, como por ejemplo los molinos de Consuegra. Aunque el no llevar la L signfique poder superar unos límites de velocidad y de consumo de alcohol, seguiré con la misma filosofía de cero alcohol al volante y respeto absoluto de las señales de tráfico.
  • Sin duda el aniversario que más orgullo me produce es que ayer se cumplieron tres años desde que dejé de fumar. Al principio iba celebrando cada semana que pasaba, hasta que llega un momento en que casi te olvidas que alguna vez fumaste. El recuerdo te vuelve cuando pasas por ambientes todavía no libres de tabaco como los bares y te das cuenta observando a la gente de hasta qué punto los fumadores son maleducados con el resto de forma en la mayoría de los casos inconscientemente. Curiosamente el olor en el que antes te sentías cómodo ahora te repugna, y casi que te vuelves más intolerante con los fumadores que los propios no fumadores de toda la vida xD
  • Tal día como hoy hace ocho años ya comenzó mi andadura en el loco mundo de las bitácoras. De entre todas las cosas que han ido sucediendo a lo largo de este tiempo me quedaría con el hecho de que una bitácora ha pasado de ser algo de “gente rara” a algo de lo más normal del mundo, a que apenas haya limitaciones técnicas para que cualquier persona pueda tener su propia bitácora, a que se hayan consolidado en muchos casos como medios de comunicación a la misma altura que los tradicionales, y en algunos casos hasta los hayan desbancado. Y esta revolución no ha hecho más que empezar :)

¡Feliz 2010!

31.12.2009 0

Creo que en los casi ocho años de vida de esta bitácora esta es la primera vez que opto por no programar la entrada. También esta será de las primeras veces que la entrada no pasará por borradores, sino que se publicará directamente…

Simplemente quería desear a todos los que de vez en cuando os dejáis caer por estos lares que tengáis un gran año 2010. Éste será un año más duro que 2009, por mucho que desde el ámbito político intenten vender lo contrario, y la única manera de superarlo va a ser trabajar todavía con más ganas de las que veníamos utilizando hasta ahora.

Hoy precisamente he leído una entrada en la bitácora de Raúl Hernández titulada “Para el 2010 quiero…”. Me gustaría citar unos fragmentos de dicha entrada:

Pero la pregunta no es “qué le pides” al 2010, sino… ¿Qué vas a hacer TÚ en 2010 para conseguir lo que quieres?

[...]

Así que al 2010 yo no lo le pido nada. Sólo espero de mí mismo ser capaz de poner toda la carne en el asador, de actuar sobre todo aquello que está a mi alcance para perseguir mis metas y mejorar mi vida y la de los que me rodean. Y la capacidad de ir aceptando lo que venga con la mejor de las disposiciones.

Luchad por vuestros sueños. Tarde o temprano los acabaréis consiguiendo. Y si nunca lo hacéis al menos nadie os podrá decir que no lo habéis intentado.

Manifiesto “En defensa de los derechos fundamentales en internet”

02.12.2009 0

Viñeta Manifiesto Eneko

Eneko/20minutos.es

Ante la inclusión en el Anteproyecto de Ley de Economía sostenible de modificaciones legislativas que afectan al libre ejercicio de las libertades de expresión, información y el derecho de acceso a la cultura a través de Internet, los periodistas, bloggers, usuarios, profesionales y creadores de Internet manifestamos nuestra firme oposición al proyecto, y declaramos que:

  1. Los derechos de autor no pueden situarse por encima de los derechos fundamentales de los ciudadanos, como el derecho a la privacidad, a la seguridad, a la presunción de inocencia, a la tutela judicial efectiva y a la libertad de expresión.
  2. La suspensión de derechos fundamentales es y debe seguir siendo competencia exclusiva del poder judicial. Ni un cierre sin sentencia. Este anteproyecto, en contra de lo establecido en el artículo 20.5 de la Constitución, pone en manos de un órgano no judicial -un organismo dependiente del ministerio de Cultura-, la potestad de impedir a los ciudadanos españoles el acceso a cualquier página web.
  3. La nueva legislación creará inseguridad jurídica en todo el sector tecnológico español, perjudicando uno de los pocos campos de desarrollo y futuro de nuestra economía, entorpeciendo la creación de empresas, introduciendo trabas a la libre competencia y ralentizando su proyección internacional.
  4. La nueva legislación propuesta amenaza a los nuevos creadores y entorpece la creación cultural. Con Internet y los sucesivos avances tecnológicos se ha democratizado extraordinariamente la creación y emisión de contenidos de todo tipo, que ya no provienen prevalentemente de las industrias culturales tradicionales, sino de multitud de fuentes diferentes.
  5. Los autores, como todos los trabajadores, tienen derecho a vivir de su trabajo con nuevas ideas creativas, modelos de negocio y actividades asociadas a sus creaciones. Intentar sostener con cambios legislativos a una industria obsoleta que no sabe adaptarse a este nuevo entorno no es ni justo ni realista. Si su modelo de negocio se basaba en el control de las copias de las obras y en Internet no es posible sin vulnerar derechos fundamentales, deberían buscar otro modelo.
  6. Consideramos que las industrias culturales necesitan para sobrevivir alternativas modernas, eficaces, creíbles y asequibles y que se adecuen a los nuevos usos sociales, en lugar de limitaciones tan desproporcionadas como ineficaces para el fin que dicen perseguir.
  7. Internet debe funcionar de forma libre y sin interferencias políticas auspiciadas por sectores que pretenden perpetuar obsoletos modelos de negocio e imposibilitar que el saber humano siga siendo libre.
  8. Exigimos que el Gobierno garantice por ley la neutralidad de la Red en España, ante cualquier presión que pueda producirse, como marco para el desarrollo de una economía sostenible y realista de cara al futuro.
  9. Proponemos una verdadera reforma del derecho de propiedad intelectual orientada a su fin: devolver a la sociedad el conocimiento, promover el dominio público y limitar los abusos de las entidades gestoras.
  10. En democracia las leyes y sus modificaciones deben aprobarse tras el oportuno debate público y habiendo consultado previamente a todas las partes implicadas. No es de recibo que se realicen cambios legislativos que afectan a derechos fundamentales en una ley no orgánica y que versa sobre otra materia.

Mis imprescindibles: Things

31.10.2009 2

Hace tiempo que decidí adoptar el método GTD a la hora de ir tratando con las tareas tanto personales como profesionales del día a día. Y aunque para seguir el GTD no haría falta usar ninguna aplicación, en mi caso decidí, después de probar varias, empezar a utilizar Things, junto a Things para iPhone.

Things

Como hay gente que ya ha explicado muchísimo mejor de lo que podría hacerlo yo qué es Things os voy a dejar con un screencast de GTD con Things obra de Berto Pena, el genio que está detrás de Think Wasabi, bitácora de obligado seguimiento si estás interesado en mejorar tu productividad sea en la plataforma que sea (que eso acaba siendo lo de menos).

10.lines do: Trucos para paperclip

12.10.2009 0

Paperclip es un plugin para Ruby on Rails que, debido a su potencia y sencillez, ha conseguido ser la elección de la mayoría de los desarrolladores a la hora de implementar de manera sencilla una solución a la hora de tener ficheros adjuntos a un modelo. Además está muy bien documentada tanto en su wiki como en los RDoc.

El ejemplo más básico de uso de paperclip sería el siguiente:

class User < ActiveRecord::Base
  has_attached_file :avatar
end

Aparte de facilitarnos la vida a la hora de la subida de ficheros, mediante su integración con ImageMagick nos permite poder generar todas las miniaturas que necesitemos de una imagen dada:

has_attached_file :image,
  :styles => { :normal => ["610x610>", :jpg], :mini => ["100x100#", :jpg] },
  :convert_options => { :all => "-strip" },
  :path => ":rails_root/public/images/articles/:id/:style.:extension",
  :url => "/images/articles/:id/:style.:extension"

En este ejemplo estamos definiendo que, para el atributo image de nuestro modelo generaremos dos miniaturas: normal, cuyo tamaño será nunca superior a 610 de ancho o de alto (lo que primero suceda) y un tamaño mini, el cual será una imagen a 100×100 px haciendo crop y en caso de que la imagen sea más ancha que alta o viceversa. Además, para ambas miniaturas se quitarán todos los datos extra de la imagen (como el EXIF) para asegurarnos de que generaremos el menor tamaño posible de imagen (más opciones para los estilos o la conversión en la documentación de ImageMagick.

Desde nuestras vistas para hacer referencia al estilo mini no tendríamos más que hacer algo como lo siguiente:

<%= image_tag article.image.url(:mini) %>

En los parámetros :path y :url vemos que se hacen uso de etiquetas del estilo :id, :style o :rails_root. Es lo que dentro de Paperclip se conoce como interpolaciones, y que a la hora de su uso se sustituyen sobre la marcha por el dato que corresponda (:style se sustituiría por "mini", basándonos en el ejemplo anterior).

Una de las opciones más interesantes, aunque quizá de las menos usadas por la gente, son la posibilidad de definir nuestras propias interpolaciones. Por ejemplo, podríamos definir una interpolación de nombre :username, incluyendo el siguiente código en el fichero config/initializers/paperclip.rb:

Paperclip.interpolates :username do |attachment, style|
  attachment.instance.username
end

El anterior código define que :username será sustituida por el atributo username de la instancia del modelo desde el que estemos usando Paperclip. De esta manera, si hiciesemos algo como lo siguiente:

class User < ActiveRecord::Base
  has_attached_file :avatar, :path => ":rails_root/public/images/:username.:extension"
end

Como resultado, al llamar a user.avatar.path tendríamos "./public/images/mayoral.png". Pensad por ejemplo en el uso de permalink_fu y una interpolación que hiciese referencia al campo que alberga el permalink de un artículo… :P

En mi caso, otra línea que suele estar frecuentemente en config/initializers/paperclip.rb es la siguiente:

Paperclip.options[:command_path] = '/opt/local/bin'

De esta manera le indico a Paperclip donde reside el ImageMagick que instalé a través de MacPorts.

Para una segunda parte de esta entrada me dejo pendiente el uso de Amazon S3 como almacenamiento y la personalización del post-procesado de los ficheros adjuntos, con los denominados processors.

Mis imprescindibles: Sequel Pro

16.07.2009 2

Iniciamos otra nueva serie de entradas dedicadas a aquellas herramientas que uso a diario y que sin duda han mejorado tanto mi calidad de vida tanto en el aspecto profesional como en algunos casos también en el personal. La aplicación que inaugura esta serie es Sequel Pro.

Sequel Pro

Sequel Pro es una aplicación libre para Mac OS X basada en el código de la ya abandonada CocoaMySQL cuyo fin es la gestión de bases de datos MySQL. Acostumbrado a utilizar en Linux las MySQL GUI Tools, en Sequel Pro me encontré como en casa.

Con una interfaz muy al estilo Mac, Sequel Pro proporciona todo lo que necesitas para poder conectarte a cualquier servidor MySQL ya sea local o remoto, una infinidad de opciones a la hora de consultar datos (ya sea de forma guiada desde la pestaña Content o de forma manual desde la pestaña Query), soporte de vistas, importación y exportación de datos, exploración y modificación de la estructura de las bases de datos, cambiar de una base de datos a otra sobre la marcha…

Una aplicación sencilla y ligera que no puede faltar en tu escritorio si parte de tus funciones están ligadas al manejo de bases de datos MySQL.

Arañando segundos: Cachés y números primos

09.06.2009 12

Cuando te dedicas a crear sitios web que van a soportar tráficos de cientos de miles de usuarios únicos al mes con millones de impactos durante esos periodos, cualquier parte de la aplicación en el que consigas reducir milisegundos redundará en un mejor aprovechamiento de la infraestructura y por tanto en una reducción de los costes de la misma, al ser capaz de incrementar el número de peticiones por segundo que puede atender tu servidor. Hoy vamos a hablar de una técnica ya usada en otros ámbitos pero que pocas veces la he visto utilizada en desarrollos web, y es el uso de números primos en la expiración de las cachés.

A la hora de identificar las cachés que conforman una página, nos podemos encontrar con dos tipos distintos de caché:

  • Permantentes: No tienen tiempo de expiración. Normalmente o no son borradas o en caso de ser borradas se realiza desde código (por ejemplo, al añadir un nuevo artículo borramos la caché que contiene el listado de los últimos n artículos).
  • Temporales: Tienen tiempo de expiración. Dentro de este tipo de caché entran aquellos módulos que no merece la pena borrar desde código, como por ejemplo datos que muestres en la cabecera o el pie que con que se refresquen cada x minutos es más que suficiente.

Dentro de los cachés temporales es frecuente encontrarse con módulos que expiran transcurrida la misma cantidad de tiempo (2 horas), o módulos que expiran transcurrida una fracción del tiempo de los módulos más tardíos (10 minutos). En un caso que tuviésemos 4 módulos que caducan a las 2 horas y 3 módulos que caducan a los 10 minutos nos encontraríamos con que realmente cada 2 horas tenemos que estar regenerando 7 módulos.

Una manera de evitar una frecuencia tan alta de regenerar todos los módulos de caché es utilizar algo tan sencillo como números primos de minutos en vez de tiempos más “redondos”. En el caso que comentábamos antes cada dos horas se producía la regeneración ya que el mínimo común múltiplo de 10 (2 x 5) y 120 (2^3 x 3 x 5) es 120 (2^3 x 3 x 5). Sin embargo, si para los 3 módulos que caducaban a los 10 minutos hubiésemos escogido los números primos que rodean a 10 (7, 11 y 13) y para los 4 módulos que caducan a las dos horas hubiésemos escogido los primos que rodean a 120 (109, 113, 127, 131), nos encontraríamos con que nunca (o más estrictamente, cada 7 x 11 x 13 x 109 x 113 x 127 x 131 = 205.122.846.929 minutos) tendríamos que regenerar las 7 cachés a la vez, y no solo eso, sino que la gran mayoría de tiempo estaríamos sirviendo o de caché todo o como mucho regenerando un módulo o dos a la vez. Al fin y al cabo, los datos seguirían siendo aproximadamente igual de actuales que si tuvieran los valores más “redondos”.

Esto mismo que hemos explicado para cachés temporales se podría aprovechar para transformar cachés permanentes en temporales. Solo habría que cambiar la escala de “minutos” a “segundos”, y tendríamos datos tan en tiempo real como un usuario se podría dar cuenta ;) Y con estos pequeños cambios simplificaríamos de gran manera nuestros controladores, algo que a su vez implica que reducimos la cantidad de errores posibles en nuestro código y a la postre reducción también en el coste de mantenimiento del mismo :)

On The Air: “Bohemian Rhapsody” de Queen

15.05.2009 3

Nueva entrega de la sección que inauguramos en febrero con el Single Ladies de Beyoncé. En esta ocasión la canción escogida es una de las consideradas como de las mejores de la historia, “Bohemian Rhapsody” de Queen.

Por si eres de ese 0,001% que no conoce la canción, aquí tienes el videoclip original:

Imagen de previsualización de YouTube

En el repaso a la videoteca, comenzaremos con la intervención de Queen en En el Live Aid de julio del 85, la cual comenzaron precisamente con Bohemian Rhapsody, cambiando en el punto operístico de la canción a Radio Ga-Ga:

Imagen de previsualización de YouTube

Guns’n'Roses, Elthon John y Queen en el concierto tributo a Freddie Mercury de 1992 hicieron su peculiar versión de la canción:

Imagen de previsualización de YouTube

Aunque para mi gusto uno de los mejores covers de “Bohemian Rhapsody” vino de la mano de Montserrat Caballé y Bruce Dickinson en el disco “Friends for life” de la soprano:

Imagen de previsualización de YouTube

No podíamos dejar el repaso de vídeos dedicados a “Bohemian Rhapsody” con uno de los últimos hits de Youtube, un cover de la canción en el que tanto instrumentos musicales como voces están hechos a base de componentes electrónicos (un scanner HP ScanJet 3C para las voces, una disquetera de 8 pulgadas para los bajos, una Texas Instruments TI-99/4a como guitarra principal…):

Imagen de previsualización de YouTube

Por último, y aunque no es un vídeo, merece mención una captura de pantalla de algo que pasó en Digg hace un tiempo. Alguien puso como primer comentario de una historia “Is this real life?”, alguien respondió a ese comentario con “Is this just fantasy?”, otro continuó con “caught in a landslide”… y el resultado final fue la letra íntegra de la canción (efectos de sonido incluidos). Merece la pena verlo :)

Actualización 12 de diciembre de 2009: Hace relativamente poco tiempo vio la luz la que probablemente sea la versión más divertida y original de esta canción, obra de los Teleñecos.

Imagen de previsualización de YouTube

It’s a happy, happy week

18.04.2009 0

Cualquiera que esté metido en el mundo de Ruby on Rails, tenga el código de sus proyectos en GitHub y use de forma habitual GMail no se podría haber imaginado que en la misma semana recibiría los tres anuncios que vamos a comentar a continuación :)

Phusion Passenger para Nginx

Hace unos días la gente de Phusion, creadores del gran Passenger anunciaba que con motivo de su primer aniversario como empresa lanzaban la versión 2.2 de Passenger, cuya principal novedad es el soporte de Nginx.

Cualquiera que haya probado Passenger al poco tiempo se ha olvidado de Mongrels, Thins y compañía para poner en desarrollo y producción Passenger, al facilitarte la vida de forma increible a la hora de hacer un deploy de una aplicación Ruby. Y cualquiera que haya probado Nginx ha estado pensando en cómo poder deshacerse de Apache, que aunque es una maravilla y tremendamente potente, no es tan rápido, ligero y eficiente como es Nginx. Desde ahora no va a ser necesario elegir entre uno u otro :D

Sistema de gestión de incidencias integrado en GitHub

GitHub, uno de los mejores proveedores de repositorios Git que existen en la actualidad, anunció la integración de un sistema de incidencias en cada uno de los repositorios que tengas.

Con el soporte de etiquetas, cierre de tickets desde el propio mensaje de los commits y demás funcionalidades, ya no va a ser necesario andar montando una copia local que integrar con un Redmine o un Trac para poder gestionar las incidencias más técnicas.

Destinatarios sugeridos en GMail

A lo largo del día, ya sea mails a los socios, a los proveedores o a los clientes, acabo mandando una cantidad de mails tremenda. En la mayoría e las ocasiones no son mails a listas de correo, sino que son mails a varios destinatarios, que por lo general coinciden de mail a mail.

Google, desde la bitácora oficial de GMail, anunció una nueva característica en los Labs (también incluida en aquellos que utilizamos Google Apps para tu dominio), que no es ni más ni menos que la sugerencia de destinatarios conforme vas escribiendo un correo.

Si normalmente cuando escribes a A también mandas copia a B, C y D, al tener activada esta opción cada vez que escribas a A y añadas a B al correo, Google te sugerirá añadir como destinatario a C y a D. He estado haciendo pruebas con los mails a varios que más habitualmente mando y la verdad es que lo está bordando :)

Sin duda estas tres noticias van a suponer una mejora en la productividad y la calidad del trabajo tremendas. O eso espero :P