sábado, septiembre 18, 2010

Aplicación de Rails 3 con MongoDB

En los últimos días he tenido que iniciar un par de proyectos en Ruby On Rails, donde la base de datos que se ha requerido es una base de datos no relacional, en este caso MongoDB.

La idea de este post es documentar la configuración de una nueva aplicación en Rails 3 para usar con MongoDB, donde vamos a desactivar ActiveRecord e instalar las siguientes herramientas:

  • Generadores Rails para Mongo
  • Rspec para pruebas
  • Factory Girl para fixtures
  • Haml como plantilla de vistas y jQuery.

Como paso inicial es necesario crear una nueva aplicación de Rails 3 - Se asume que ya se tiene instalado Rails 3 y MongoDB -, pero vamos a pasar las opciones -O para que no se creen archivos de ActiveRecord, -J para que no se instale la librería de javascript Prototype y -T para que no cree el fólder para Test::Unit

$ rails new mi_app -O -J -T

Después de creada la aplicación, seria buena idea inicializar un repositorio de Git.

Una vez creada nuestra aplicación hay que realizarle algunas adiciones nuestro archivo Gemfile para agregar las dependencias de nuestra aplicación:

  • mongoid y bson_ext => Mongoid es la librería que usaremos para conectarnos a la base de datos de MongoDB y bson_ext es una extensión en C para acelerar la serializacion de BSON
  • haml => Lenguaje de plantilla alternativa para vistas en Rails, desde mi punto de vista menos verbal y mas "developer friendly" que html y erb.

Dentro de un grupo llamado :development agregamos las siguientes gemas:

  • rails3-generators => varios generadores para Rails 3, lo que nos permite ejecutar rails generate
  • haml-rails => generadores de haml para Rails 3
  • jquery-rails => generadores de jquery para Rails 3

En el grupo :test agregamos:

  • rspec => framework para pruebas en Ruby
  • rspec-rails => utilerias para pruebas en RSpec para Rails
  • factory_girl_rails => utileria para la creación de modelos para pruebas
  • remarkable_mongoid => librería para pruebas de modelos de mongoid con RSpec

El archivo Gemfile debe de quedar como se muestra a continuación.



Para instalar las gemas solo ejecutamos

$ bundle install

Para conocer mas de las gemas instaladas aquí les dejo los vínculos a sus referencias

Una vez instaladas las gemas hay que realizar algunas configuraciones, lo primero es configurar mongoid para trabajar con Rails y desactivar ActiveRecord, para eso ejecutamos el comando:

$ rails generate mongoid:config

Este comando va crear el archivo config/mongoid.yml donde vamos a configurar el acceso a la base de datos de MongoDB, también va a modificar el archivo config/application.rb y va a eliminar la dependencia de ActiveRecord, la parte superior de config/application.rb deberá quedar algo similar a:

# require "active_record/railtie"

require "action_controller/railtie"

require "action_mailer/railtie"

require "active_resource/railtie"

#require "rails/test_unit/railtie"

Ya que estamos en el archivo config/application.rb vamos indicandole a Rails que en nuestra aplicación deseamos usar haml, rspec y factory_girl por omisión, para esto dentro de la declaración de la clase Application < Rails::Application, pero al final agregamos el siguiente código



A partir de este punto instalamos el soporte para jQuery y Rspec en nuestra aplicación de la siguiente forma:

$ rails generate jquery:install #--ui para activar jQuery UI

$ rails generate rspec:install

Como ultimo paso vamos configurar RSpec para que trabaje con factory_girl y remarkable, ademas de eliminar el soporte a ActiveRecord y hacer que RSpec elimine las colecciones creadas en MongoDB por nuestras pruebas antes de la ejecución de cada prueba, esto es necesario para asegurarnos que al correr cada prueba la base de datos este "limpia" y así no crear conflictos y/o dependencias en las pruebas.

Al inicio del archivo spec/spec_helper.rb hay que requerir:

require 'factory_girl'

require 'remarkable/mongoid'

Un poco mas abajo indicamos que cargue los archivos Factory de factory_girl

Dir[Rails.root.join("spec/factories/**/*.rb")].each {|f| require f}

Después eliminamos el soporte a ActiveRecord comentando las siguientes lineas:

config.fixture_path = "#{::Rails.root}/spec/fixtures"

config.use_transactional_fixtures = false

Y finalmente dentro y al final del bloque de configuración de RSpec indicamos que antes de cada prueba elimine las colecciones de MongoDB

config.before :each do

Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)

end

El archivo spec/spec_helper.rb deberá quedar muy parecido a



Una vez en este punto ya podemos proceder a crear nuestra súper aplicación usando MongoDB como base de datos, si ejecutamos el generador para model, o controller o scaffold, Rails 3 generara modelos para MongoDB o vistas en haml y creara los archivos necesarios en spec para realizar pruebas con RSpec.


4 comentarios:

megusta dijo...

¿Porqué después de configurar tantas herramientas puedes crear una super aplicacion? Porqué se tiene tanta devocion por Ruby On Rails si desde el punto de vista de negocio siento que es demasiado complicado simplemente configurar el ambiente para poder empezar a desarrollar un super aplicacion como dices

Mario Alberto Chavez dijo...

@megusta;

En realidad no necesitas hacer cambios en la configuración, si lo que quieres es realizar una aplicación con los Defaults de Rails.

En este caso en particular no busco crear una app con base de datos relacional, por lo tanto es necesario cambiar ese aspecto. Realmente no me parecen complicados los pasos, y menos si los comparo con otros frameworks para hacer exactamente lo mismo, son cambios que no te llevan mas de 10 minutos.

megusta dijo...

Mario gracias por responder, pero estaras de acuerdo en que son muchos pasos? en la plataforma .net obviamente sucede lo mismo solo que la herramienta visual studio los realiza tras bambalinas, sin embargo, sigo sin encontrar el valor que representa Ruby para cualquier empresa o corporativo que tiene necesidades de desarrollo de software en casa o personalizado. En la empresa donde trabajo las herramientas e incluso los componentes de terceros que decidimos utilizar para un desarrollo, terminan siendo evaluados a detalle para determinar el impacto en costo que estos tendran a futuro simplemente por hecho de soportarlos o incluirlos, es por ello que al ver tanta herramienta mi pensamiento me lleva a pre decir como sera soportada a la larga una aplicacion con semejante numero de dependencias que evolucionan de forma independiente y que sin duda dejaran de ser soportadas o quedaran obsoletas.

Es por ello que el entrar a ver el mundo de software libre termino percibiendo que sera libre pero igual de caro que el sopftware propietario.

Que opinas? Por favor dame un punto de vista que pueda orientarme.

Muchas gracias.

Mario Alberto Chavez dijo...

megusta;

En lugar de comentar aqui, cree este nuevo post mas detallado http://mario-chavez.blogspot.com/2010/09/la-complejidad-de-ruby-on-rails.html

Saludos