lunes, 1 de octubre de 2012

Migraciones en Rails

Trabajar con Rails implica utilizar el patrón de desarrollo MVC (Modelo-Vista-Controlador), en el cual mantenemos separados entre sí los datos, la lógica y las interfaces gráficas; para así tener una mejor organización del código y facilitar su mantenimiento y evolución.

Antes de comenzar

Lo primero que debemos hacer antes de escribir la primera línea de código es definir y diseñar los Modelos que representen la información que será manipulada por nuestra aplicación. Pienso que ésta es la parte más importante en la etapa de desarrollo de un sistema, por lo que recomiendo dedicarle todo el tiempo, atención y cuidado posible.

Para diseñar los modelos debemos tener completamente definidas las características y requerimientos del sistema que desarrollaremos. A partir de esta información, podemos crear diagramas y otra documentación que posteriormente nos será de ayuda para el modelado de datos.

Modelos y Migraciones

Los Modelos nos permiten manipular desde Rails los datos que se encuentran almacenados en nuestra base de datos relacional (PostgreSQL, MySQL, SQLite, etc); por tanto su estructura y definición dependerán de la estructura y definición de nuestra Base de Datos.

Las Migraciones nos permiten crear y modificar nuestra base de datos de manera organizada y estructurada; ademá de que reduce casi completamente el uso de SQL. También nos permiten manejar versiones del estado de la base de datos (es como utilizar un CVS exclusivo para la base de datos).

Como era de esperarse, ambos son definidos en Ruby, y una característica super importante es que son independientes de todo manejador de base de datos, por lo que no tenemos que preocuparnos por particularidades de cada uno.

Este post se lo dedicaré exclusivamente a las Migraciones.

Crear Migraciones

Para crear una migración, usamos el siguiente comando:

$ rails generate migration NombreDeLaMigracioón

Lo cual nos generará un archivo como este:

class NombreDeLaMigración < ActiveRecord::Migration
  def change
  end
end

La ubicación predeterminada del archivo es db/migrations/, y el nombre del archivo tendrá el formato YYYYMMDDHHMMSS_nombre_de_la_migracion.rb:

db/migrations/YYYYMMDDHHMMSS_nombre_de_la_migracion.rb

El timestamp YYYYMMDDHHMMSS es asignado automáticamente por Rails

Escribir Migraciones

Ya que hemos creado nuestra migración, procedemos a definirla para construir nuestra base de datos. ActiveRecord::Migration nos ofrece un conjunto de métodos que podemos utilizar para crear y modificar tablas y columnas. Como ejemplo crearemos los modelos Producto y Categoría:

# db/migrations/20121001220247_crear_productos.rb

class CrearProductos < ActiveRecord::Migration
  def up
    create_table :productos do |t|
      t.string :nombre
      t.string :descripcion
      t.float :precio
      t.timestamps
    end
  end

  def down
    drop_table :productos
  end
end


# db/migrations/20121001220434_crear_categorias.rb

class CrearCategorias < ActiveRecord::Migration
  def up
    create_table :categorias do |t|
      t.string :nombre
      t.timestamps
    end
  end

  def down
    drop_table :categorias
  end
end

Ahora analicemos detenidamente:

  • En el método up definimos las adiciones o modificaciones que deseamos aplicarle a la base de datos.
  • En el método down definimos las acciones opuestas a las del método up. De esta manera, Rails sabrá qué hacer cuando queramos revertir alguna migración.
  • Los tipos de datos soportados por Rails son: binary, boolean, date, datetime, decimal, float, integer, primary_key, string, text, time y timestamp.
  • Sin necesidad de especificarlo, Rails por defecto genera un campo id (primary_key) para cada tabla.
  • timestamps es un helper que genera los campos created_at (fecha y hora de creación) y updated_at (fecha y hora de la última actualización). Estos campos (al igual que el campo id) son gestionados por Rails.
  • En Rails 2.1 se introdujo el método change, en el cual indicamos únicamente las instrucciones de adición o modificación (similar a las indicadas en el método up); sin necesidad de especificar las instrucciones de reversión (del método down). De esta manera, será Rails quien se encargue de determinar las acciones de reversión adecuadas. Si reescribimos la anterior definición haciendo uso del método change, obtenemos:
# db/migrations/20121001220247_crear_productos.rb

class CrearProductos < ActiveRecord::Migration
  def change
    create_table :productos do |t|
      t.string :nombre
      t.string :descripcion
      t.float :precio
      t.timestamps
    end
  end
end


# db/migrations/20121001220434_crear_categorias.rb

class CrearCategorias < ActiveRecord::Migration
  def change
    create_table :categorias do |t|
      t.string :nombre
      t.timestamps
    end
  end
end

Las definiciones soportadas por el método change son:

  • add_column: añadir columna
  • add_index: añadir índice
  • add_timestamps: añadir timestamps
  • create_table: crear tabla
  • remove_timestamps: eliminar timestamps
  • rename_columns: renombrar columna
  • rename_index: renombrar índice
  • rename_table: renombrar tabla

Más Opciones

También podemos definir propiedades específicas de las columnas:

# valores por defecto
t.decimal :price, default: 0.0

# presencia
t.string :email, null: false

# índice de unicidad
# -- después del método up o change
add_index :users, :email, unique: true

Ejecutar Migraciones

Para ejecutar las migraciones hacemos uso de Rake, el cual generará o actualizará el archivo db/schema.rb según las definiciones indicadas en las migraciones. Este archivo representa el estado físico de la base de datos.

// ejecutar todas las migraciones que no hayan sido ejecutadas aún
$ rake db:migrate

También podemos ejecutar una migración en específico indicando su timestamp:

$ rake db:migrate VERSION=19700101000000

Revertir Migraciones

Podemos revertir migraciones de varias maneras:

// revertir la última migración
$ rake db:rollback

// revertir las últimas 4 migraciones
$ rake db:rollback STEP=4

// resetear la base de datos (borrar, crear y migrar)
$ rake db:reset

Pueden conseguir más información en Ruby on Rails Guides: Migrations.

En el próximo post les mostraré como generar, configurar y asociar Modelos; los cuales nos permiten manipular la base de datos desde Rails de una manera bastante sencilla y práctica.

viernes, 14 de setiembre de 2012

Instalando RVM, Ruby, JRuby y Rails Parte 2: El Final Feliz

Si siguieron los pasos indicados en el primer post, es probable que no hayan tenido exito al intentar configurar y trabajar con Rails y JRuby; y lo digo porque personalmente tuve que rehacer todo el proceso.

Luego de varias leidas de documentaciones oficiales, les presento el procedimiento de instalacion que definitivamente resulto ser todo un exito en mi equipo con Ubuntu 12.04:

Eliminar todos los rubies

Para comenzar eliminamos todos los rubies que hayamos instalado con RVM:

$ rvm remove jruby-1.7.0.preview2
$ rvm remove 1.9.2
$ rvm remove 1.9.3
$ rvm remove ...

Instalar Ruby MRI 1.8.7

Normalmente Ubuntu trae instalado el interprete 1.8.7 de Ruby MRI, pero RVM recomienda instalarlo nuevamente a traves de la herramienta:

$ rvm install 1.8.7
...
$ rvm 1.8.7
$ rvm list

rvm rubies

=> ruby-1.8.7-p370 [ x86_64 ]

Instalar Ruby MRI 1.9.3

Ahora instalamos la ultima version estable del interprete, no sin antes asegurarnos de que poseemos todas las librerias y paquetes requeridos:

$ sudo apt-get install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion pkg-config
...
$ rvm install 1.9.3
...
$ rvm list

rvm rubies

=> ruby-1.8.7-p370 [ x86_64 ]
   ruby-1.9.3-p194 [ x86_64 ]

Instalar JRuby estable

Si deseamos trabajar con JRuby (implementacion de Ruby que es ejecutada por JVM), seguimos estos pasos:

// instalar librerias y paquetes requeridos por JRuby
$ sudo apt-get install curl g++ openjdk-6-jre-headless

// no olviden seleccionar a Ruby 1.9.3 antes de proceder
// -- a instalar JRuby
$ ruby 1.9.3 
$ rvm install jruby-head --1.9
...
$ rvm list

rvm rubies

   jruby-head [ x86_64 ]
   ruby-1.8.7-p370 [ x86_64 ]
=> ruby-1.9.3-p194 [ x86_64 ]

Instalar Rails

Como deseamos trabajar en Rails bajo JRuby, lo seleccionamos antes de proceder:

$ rvm jruby-head
$ gem install rails

Configurar nueva app en Rails

Como ven todo el procedimiento fue un paseo y ya tienen todo lo necesario para empezar a crear aplicaciones en Rails bajo Ruby o JRuby.

Existen distintos templates que nos permiten generar aplicaciones en Rails que cumplan determinadas caracteristicas. En mi caso he generado una aplicacion que funcione con PostgreSQL en ambiente de produccion, SQLite3 en ambiente de desarrollo; ademas de soportar HTML5, HAML, SASS y el fron-end framework Twitter Bootstrap:

// instalar librerias y paquetes requeridos
$ sudo apt-get install libsqlite3-dev libpq-dev

// generar nueva app con template deseado
// responder 'yes' a 'HAML', 'Twitter Bootstrap with Sass' y
// -- 'rails-footer'
// responder 'no' a todo lo demas
$ rails new [app_name] -m https://raw.github.com/RailsApps/rails3-application-templates/master/rails3-haml-html5-template.rb -d postgresql

Para asegurarnos de que la aplicacion pueda ser ejecutada localmente, hacemos lo siguiente:

// agregar al Gemfile
gem 'therubyrhino'

// luego ejecutar
$ jruby -S gem install therubyrhino

// o tambien
$ bundle install

// probar que todo funcione al pelo
$ rails server

Que tal les fue con la instalacion? Estan listos para empezar a codear durisimo con Ruby on Rails?

jueves, 6 de setiembre de 2012

How to use RVM [Video]

Comparto con ustedes este interesante video sobre instalacion y uso de RVM (audio en ingles):

martes, 4 de setiembre de 2012

Instalando RVM, Ruby, JRuby y Rails

Antes de entrar en accion con Ruby, primero necesitamos configurar y preparar nuestro equipo.

Aqui te indico paso a paso como instalar y configurar RVM, Ruby, JRuby y Rails en Ubuntu 12.04 LTS:

RVM + Ruby

curl -L https://get.rvm.io | bash -s stable --ruby
source /home/djgrill/.rvm/scripts/rvm

En el sitio web oficial de RVM tienen una muy buena documentacion acerca de como instalar el paquete segun nuestras preferencias. En mi caso decidi instalarlo con el interprete de Ruby incluido, asi que esas 2 lineas de comando me fueron suficientes.

Nota: es probable que tengas que modificar el archivo de configuracion de Bash (ubicado normalmente en ~/.bashrc). Simplemente añade la siguiente linea al final:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"

Finalmente cierra y reabre el terminal (para que el shell reconozca el nuevo comando) y verifica que tanto RVM como Ruby funcionen correctamente:

rvm list
ruby -v

JRuby

Ya que tenemos RVM funcionando, podemos usarlo para instalar JRuby:

rvm install jruby-x.y.z

Actualmente se encuentra disponible el segundo preview del proximo release 1.7 (1.7.0.preview2). A finales de la proxima semana planean lanzar a peticion de la comunidad la version 1.6.8, pero no sera hasta finales de Septiembre que saldra a la luz la version estable 1.7 luego de 1.5 años de desarrollo.

Rails

Finalmente instalamos la gema de Rails:

gem install rails
rails -v

En mi caso tuve que primero cambiar de entorno en RVM a JRuby con:

rvm use jruby-x.y.z

Ademas de instalar el paquete zlib:

apt-cache search zlib
sudo apt-get install zlib-bin

Con esto ya tenemos todo lo necesario para empezar a codear como los dioses. Si necesitas ayuda o deseas aportar informacion, no dudes comentar!

Happy Rubying!