Ruby on Rails, o por qué lo elegí en lugar de Django

Sí, el título es una mención directa al post de Tabo, “Django, Or why I chose it over turbogears and ruby on rails.”

¿Por qué elegí Rails en lugar de Django? Una sola palabra: Ruby.

Podría mencionar muchas cosas acerca de la convención sobre configuración, Active Record, erb y el magnífico soporte de AJAX, pero lo cierto es que, tal como dijo David Heinemeier Hansson (el autor de Rails), “Rails no sería Rails si no es por Ruby.”

La belleza de Rails proviene de Ruby, ese lenguaje de programación todavía nuevo, donde es posible hacer cosas de manera tan expresiva y divertidas (uno no escucha esa palabra muy a menudo últimamente) que simplemente tu productividad aumenta considerablemente. Ya no te detienes a pensar cuál era la sintaxis de str_pad(), ni tampoco memorizar “from django.shortcuts import render_to_response, get_object_or_404”, sino simplemente hacer tu aplicación.

Antes de aprender Rails, me puse a aprender Python y Django. Ya había visto un poquito de Python y era un lenguaje que me llamaba la atención. Ruby para mí era exactamente como el japonés — algo desconocido y foráneo. De modo que mi primera elección fue la ruta de la culebra.
Cuando me senté a aprender Django encontré algunas trabas que no me gustaron, pero que alegremente estuve dispuesto a aceptar hasta quizás acostumbrarme. Como por ejemplo, tener que teclear “from django.shortcuts import render_to_response” para mostrar una plantilla, algo que el tutorial mismo dice, es tarea común — y si es común, ¿por qué no viene por defecto? No hay problema, mi editor puede escribir todo eso por mí.
Luego me encontré con esta parte de Generic Views, donde el encabezado de la documentación dice: “Generic Views: Menos código es mejor” y luego proceden a mostrarte unas líneas monstruosas como “django.views.generic.list_detail.object_detail” y “django.views.generic.list_detail.object_detail”.
Me pareció una contradicción, pero no me hice líos. Puedo memorizar todo eso y en su momento lo hice.
No sé si el Magic Removal branch ahorra todo esto, pero veo el mismo código en el tutorial.

Estuve un par de semanas con un par de horas por las noches aprendiendo poco a poco y construyendo una aplicación web sencilla (“chifa,” el website exclusivo para mezclar wantan, palta y chijaukai y ver qué evoluciona del resultado). Django trae un servidor web propio para desarrollar tu aplicación sin trabas, pero extrañamente cuando grababa cambios a un script en Python y éste tenía un error de sintaxis, el servidor web se colgaba con una excepción. Tenía que pulsar CTRL+C y reiniciarlo. Como tengo la costumbre de grabar constantemente esto me fue irritando.
Continué así un tiempo, aprendiendo en silencio hasta que viajé a Lima y Antonio me animó a aprender Ruby (y Rails). En otro post trataré de ahondar en este tema, pues tiene mucho que ver con un montón de sucesos que el Señor me ha ido mostrando en esta primera mitad del año que me parece increíble — um, pero eso es tema de otro post.

Versión resumida: regresé a Ica con el interés en Ruby on Rails y, después de un par de días de resumir mis clases de colegio con Python, me dije “Bueno, vamos a probar ver Ruby por una noche.” No me haría daño, ¿verdad?

El hecho es que probé Ruby y jamás dí la vuelta atrás.

No recuerdo la última vez que me he sentido tan fascinado por un lenguaje. Ahora que lo pienso, creo que nunca me he sentido fascinado por un lenguaje… ni siquiera por PHP, que, tras haber visto Ruby, me parece… prehistórico.

Pero bueno, estamos hablando de Rails y no de Ruby — pero es que la verdad no se puede hablar de Rails sin tropezar con la belleza de Ruby. No entiendo a qué se refiere Tabo cuando dice que el lenguaje no es “limpio” — lo que sé es que es expresivo y legible. Bello. Y uno se siente raro usando esa clase de adjetivos para describir un programa, pero tarde o temprano se vuelve inevitable. Eres feliz.

Basta de sentimientos cursis, vamos a lo técnico.

Convención sobre configuración
Este es un concepto importante de Rails, y quiere decir que, a menos que se especifique lo contrario, existe una convención o forma standard de comportamiento o nombramiento para cosas comunes. Esto nos ahorra bastante tiempo.
Por ejemplo, para una tabla “alumnos” de la base de datos se espera que la clase que va a manejarla se llamará “alumno” (singular). Rails tiene todo un sistema de pluralización que es fácilmente extensible para el caso del español. Pero el concepto va más allá. Y eso nos lleva a…

Rails es menos código
En Django tienes que especificar siempre qué plantilla vas a mostrar retornando un objeto HttpResponse. ¡Para la práctica totalidad de páginas tienes que hacer “from django.shortcuts import render_to_response”!
En Rails, gracias a la convención sobre configuración, se asume que a la acción “lista” le corresponde una vista “lista.rhtml”. No hay nada extra qué especificar. Si quisiéramos que la acción use una vista de distinto nombre, lo decimos de manera simple y expresiva:

render :action => “lista_filtrada”

Oh, la convención es que la extensión de la vista puede ser “.rhtml”, así que tampoco es necesario especificar eso. En Django viene a ser algo así como:

return render_to_response(‘alumnos/lista_filtrada.html’, {‘lista_alumnos’: lista_alumnos})

Igualmente, para usar las bondades el ORM de Django tenemos que especificar el modelo que queremos usar:

from itskool.alumnos.models import Alumno

En Rails no hay necesidad de especificar nada.

RailsRuby es más expresivo
Estoy enamorado de poder decir:

  • if expiracion > 30.seconds.ago
  • limite_maximo = 4.megabytes
  • create_table :alumnos do |t|
      t.column nombre, :string
      t.column apellidos, :string
      t.column fecha_nacimiento, :date
    end

Aparte Ruby nos permite hacer cosas fabulosas que lastimosamente no caben aquí y es materia de otro post.

Rails no tiene URLs flexibles
A diferencia de Django, el routing de Rails no es tan flexible. Esto se debe a que Django usa expresiones regulares, mientras que Rails está basado en elementos separados por slashes (“/”).
La pregunta es, ¿cuántas veces vamos a usar esa flexibilidad? Ok, puede servir para mantener la estructura de URLs de un proyecto que estamos portando a Django, ¿mas cuántas veces sucede eso? Si la idea es tener URLs bonitos, creo que “/noticias/2005/05” es suficientemente bonito y limpio para la gran mayoría de casos.

El problema de la flexibilidad de las URLs Django es que tiene un precio muy alto: los desarrolladores se ven forzados a crear un método en el modelo para generar la URL correcta para la vista (el afamado get_absolute_url()), una clara violación del DRY y del MVC. El mismísimo Adrian Holovaty acepta que esto es feo, pero que no hay mejor solución por el momento.
Esta complicación no me parece que justifique una flexibilidad que en el 80% de los casos no se va a aprovechar.

Rails no sufre de este problema.

Active Record rulez!
En Rails lo normal es crear las tablas en la misma base de datos y Rails automáticamente adopta los campos de cada tabla. Si alteramos una tabla y agregamos un campo lo podemos usar inmediatamente en Rails.
En Django, la estructura de la tabla se define en el mismo modelo de Django, lo cual es genial porque sirve de abstracción a la base de datos — no importa si es MySQL o PostgreSQL, sólo tienes que correr el mismo script. Rails puede hacer lo mismo. Se llama migraciones y es más cool, pero sigamos con Django.
En Django, si altero una tabla para agregar un campo tengo dos opciones:

  • Hacer la modificación en mi modelo y volver a crear la tabla — perdiendo así los datos que tengo en ella. Esto es incómodo en muchos casos.
  • La otra opción es alterar la tabla en la base de datos con un ALTER TABLE y luego agregar el campo en el modelo. Dos veces lo mismo. Y al hacer un ALTER TABLE se pierde la magia de la abstracción que Django pretendía evitar.
  • Si nos interesa tener un esquema de la base de datos así abstraído lindo como Django,existen las migraciones. Lo genial de las migraciones es que se definen en un script donde puedo hacer y deshacer los cambios. Por ejemplo, esta es una migración para renombrar un campo:

    class RenombrarNickAApodo < ActiveRecord::Migration   def self.up     rename_column :alumno, :nick, :apodo   end   def self.down     rename_column :alumno, :apodo, :nick   end end Con este esquema puedo subir estos ficheros de migración a mi servidor de producción y hacer todos los cambios que ya probé localmente. Y si rompí algo, puedo deshacerlo en el instante. Lindo, ¿verdad? Algunas cosas que quería mencionar más en profundidad, pero bueno, me he quedado sin tiempo: Django es una excelente pieza de código, probado y desarrollado "en el campo." Se nota bastante su origen orientado a websites de periodismo, el módulo out-of-the-box de administración es un gran plus, y espero que pronto hagan algo similar en Rails -- una buena idea para un proyecto personal. Mirando debajo del capó de Rails, te das cuenta que su naturaleza es diferente, tanto en su funcionamiento como en su filosofía. Rails tiene un fabuloso soporte de Ajax y la comunidad es mucho más grande que la de Django y crece a un ritmo vertiginoso. Las personas que encabezan esta comunidad son programadores brillantes. Django es bastante capaz, pero Rails lleva, por el momento, la delantera por un gran margen.

    Responses

    1. Pingback: Nikolas Valcarcel
    2. Genial que hayas encontrado al fin algo mejor a PHP :-)

      Sobre algunos puntos de tu post:

      Tienes razón sobre lo de Ruby, es muy buen lenguaje dentro de su enfoque, pero su fuerte es también su debilidad (al menos en mi punto de vista): su excesiva expresividad. Es por esto que mencionaba en un post anterior que Ruby es una especie de P erl maquillado.

      Por ejemplo, si me das a escoger un lenguaje en el que pueda escribir poesía, probablemente escogería P erl, o el mismo C. Lamentablemente esta expresividad es tambien contraproducente para trabajar en equipo. Genial si eres un lonely hacker, pero cuando escribes algo con otros o que otros van a mantener, la expresividad es nociva. Y ese justamente me parece el punto fuerte de Python, bajo el punto de vista de un perlero o uno de los nuevos “rubistas” probablemente sea un lenguaje “aburrido”, pero en lo personal considero que un lenguaje que fomente la homogenización de código y que hasta cierto punto LIMITE la “creatividad alocada” de los programadores, es un lenguaje excelente para ser usado en equipos.

      Por algo tenemos el “There’s more than one way to do it” de P erl versus el “There should be one– and preferably only one –obvious way to do it”. La primera filosofía se ajusta mejor a los lonely hackers, la segunda a programadores que tienen que trabajar en equipo. A los rubistas les gusta mas la primera ;-)

      Como te mencionaba ayer, ya estoy viejo y me he vuelto flojo. No me gusta ver código ambigüo. Prefiero mil veces lo explícito a lo implícito (otro de los mantras de Python).

      Sobre lo de la contradicción que ves en los generic views, lo de menos código se refiere al código que te ahorras usando generic views. Mira por ejemplo http://www2.jeffcroft.com/2006/may/02/django-non-programmers/ donde un no programador explica como hizo uno de los blogs mas envidiados (luego del css reboot) con generic views.

      Sobre los imports, de nuevo, es por explícito es mejor que implícito. Cuestión de filosofías ;-)

      Sobre lo de las migraciones de rails, eso si es un buen punto. Aunque igual mucha gente en rails sigue haciendo sus migraciones directamente en el SQL, y esa es justamente la manera como hacemos las migraciones en producción a nuestros clientes cuando se ajustan los modelos en sus aplicaciones en django, un script .sql que se ejecuta en su BD, la herramienta de migración universal :-)
      Ya estan trabajando en un migrador para Django basado en el de rails y en otros de Java. Personalmente no creo que lo use, me siento mas tranquilo usando SQL.

      Sobre lo del tamaño de las comunidades te doy toda la razón, pero recuerda que detras estan los lenguajes y la comunidad de Python sigue siendo bastante mas grande que la de Ruby, y mas antigua por la que hay una diferencia abrumadora en la cantidad de librerías disponibles para ambos lenguajes _en_la_actualidad, aunque obviamente esta diferencia se va a ir reduciendo por el momentum actual de RoR.

      Pero de todas maneras sigo con mucho interés el progreso de RoR, no tanto por Ruby ni por Rails en si, sino por la filosofía que tienen. El loudthinking de DHH es uno de mis blogs obligatorios.

      Para terminar este comment (que ya parece escrito por gnrfan por lo largo que está quedando), quería hacer notar que en realidad entre Django y RoR hay muchas mas similitudes que diferencias, algo que los mismos AH y DHH notaron luego del Snakes and Rubies. Y lo gracioso es que ambos frameworks, Django y RoR, fueron creados por refugiados de los horrores de PHP. Y ni viene al caso mencionar su opinión de Java como plataforma de desarrollo web ;-)

      De nuevo, felicitaciones por haber encontrado algo definitivamente mejor a PHP!

    3. Que.. bueno.. 1 mas.. en ruby on rails.. :-) yo estoy en rails desde diciembre del año pasado.. es sensacional.. sin duda.. (L).. saludos.. y suerte.

    Comments are closed.