Rails es un framework de desarrollo web que implementa el patrón Modelo - Vista - Controlador, esto es, establece unas normas y unos formatos para que no mezclemos lo referente al modelo de datos de la lógica de la aplicación y de las vistas o presentación.

Algunas de las ventajas del patrón MVC son (que seguro las sabéis):

  • código más limpio: el ejemplo más claro es no encontrarse en las vistas consultas a base de datos
  • orden: si queremos modificar una vista vamos a la carpeta views, si queremos modificar un controlador al fichero correspondiente de la carpeta controllers, etcétera
  • más DRY y menos código: todo esto produce que escribamos las cosas una sola vez, lo que permite reducir el número de líneas de código y, por tanto, el número de errores en ellas

Hasta ahora habían aparecido entornos que intentaban implementar este patrón, pero no siempre quedando el código de la manera más limpia posible, quedándose en pseudo implementaciones que comenzaron a llamarse de 2 capas o de 2 capas y media.

Rails sin embargo, gracias a su sistema de convenciones, te permite seguir casi a rajatabla este patrón (por supuesto que te da la libertad para no hacerlo y mezclarlo todo en una capa, al más puro estilo PHP básico), lo cuál, a su vez, te permite modificar tu paradigma de programación y tener siempre presente la separación en tres capas para factorizar y reestructurar el código. Este hecho es comunmente conocido entre los desarrolladores de Rails como "nunca mi código va a ser perfecto".

Pero volviendo al tema que nos atañe, que no es más que una pequeña (o no tan pequeña) cuestión que se planteó hace unos días en la lista del core de Rails acerca de si tiene sentido que los helpers estén orientados al modelo de datos, o de cómo hay una ligadura intrínseca entre el modelo de datos y ciertas partes de la presentación. El hilo en cuestión se llama Object Oriented Helpers.

Pero antes de entrar en materia, veamos primero un ejemplo real de La Coctelera: en la vista de un post se introduce un código en RDF para el funcionamiento de los trackbacks, algo tal que así:

 

Esto se podría incluir perfectamente en un helper del controlador posts quedando la vista así:

<%= trackback_code(@post) %>

Hasta aquí todo bien, ¿pero qué pasa si tenemos varios tipos de posts? Si queremos reutilizar el mismo helper (que va a ser que sí, porque somos chicos DRY) tendríamos que incluir unos feos condicionales del estilo:

 if post.class == Post
  ...
 elsif post.class == Pagepost
  ...
 end
 

Es decir, que tendríamos un código bastante más sucio (pero muy DRY, eso sí).

La otra opción sería definir el helper para la clase Post y para la clase Pagepost, con el inconveniente que, dos métodos que hacen los mismo, pero que son específicos de una clase o de otra, deben de tener distinto nombre, con la pequeña sobrecarga de esfuerzo mental que esto puede requerir:

<%= trackback_code_posts(@post) %>

<%= trackback_code_pagepost(@pagepost) %>

Viendo este código (bueno, este exactamente no, pero sé que me entendéis) alguien pensó que eso no es más que un helper dependiente del modelo (de la clase) y que se podría reescribir de la siguiente manera:

<%= @post.trackback_code %>

<%= @pagepost.trackback_code %>

A pesar de que la sintaxis es ideal, es una pequeña atrocidad y una lástima, pero estamos incluyendo parte de la presentación en el modelo de datos (al contrario de como se hacía en PHP, vaya), lo cuál es malo porque:

  1. no es su lugar
  2. un modelo debe ser independiente de su representación: pensad que podemos querer ver un post en un feed, en nuestro navegador web o en texto plano
  3. cuando queramos modificar algo de la presentación ya tendríamos dos lugares en donde buscar: el modelo y la vista asociada

Sin embargo sí que resulta bastante interesante y se puede plantear de tal forma que dinámicamente se carguen helpers como métodos del modelo, vía un mixin, con lo cuál:

  1. no hay presentación en el modelo de datos
  2. se puede utilizar la sintaxis que arriba os he puesto

Y la forma de implementarla no está clara, pero se dan algunas pinceladas en el hilo del que os he hablado antes. En primer lugar existe un patrón que se llama Presetation Model que sirve justamente para esto. Además, en el propio hilo se enlaza un post titulado Rails Model View Controller + Presenter? que explica justamente cómo implementar un Presenter en Rails.

En segundo lugar, David, en su intervención en la Conferencia Rails Hispana nombró algo sobre Presenters, sin embargo he estado buscando entre el código de la 1.2 y no he encontrado nada. No sé si se refería entonces a Rails 2.0 o lo nombró de pasada como una nueva feature que han desarrollado para la próxima aplicación que lanzarán en 37 signals (el famoso CRM), así que aquí pido el comodín del público, y si alguien sabe algo o recuerda algo más, que por favor lo diga en los comentarios.

Conclusión

La conclusión es que no hay conclusión y que es un tema abierto y que va a estar activo los próximos meses: por un lado parece que a los miembros del core no les termina de convencer su uso, o que por lo menos es un asunto que quieren meditar más. Si al final se deciden parece que no va a ser en la inminente versión 1.2, sino que será para más adelante.

También parece que están formalizando un plugin, que está aún muy verde, sin documentación ni tests, y que además puede que rehagan de cero. Puede ser el primer paso para experimentar con este nuevo planteamiento.

¿Vosotros qué pensáis?

Por cierto, querido lector fiel que has llegado hasta el final: ¡Feliz Año!