Apuntes Rails: Migraciones

Publicado el Martes, 21 de agosto de 2012

Hace un tiempo publiqué un par de posts sobre Rails denominados Apuntes Rails. Mientras iba estudiando Ruby on Rails, procesaba las anotaciones y las armaba en forma de post. La segunda instancia en esa "serie" fue sobre los Controladores.

Desde entonces no he usado mucho Rails, sí otros frameworks en Ruby como Sinatra y Cuba. Sin embargo fueron quedando borradores y apuntes por ahí sobre Rails. Para no desaprovechar lo ya escrito, hoy vuelvo a publicar estos apuntes, ya de paso viendo qué interes hay en que siga con esta serie. Como comentaba, últimamente he estado viendo otras tecnologías sobre las que me gustaría escribir, pero si hay interés, puedo plantearme una meta de cubrir algunos temas más de las guías de Rails:

Migrations - Persiste tus datos

Migrations - Persiste tus datos

Siguiendo con los apuntes de Rails Guides. En este caso la herramienta por defecto -bastante práctica- para mantener la base de datos de una aplicación: Rails: Migrations.

Las migraciones son clases Ruby que heredan de ActiveRecord::Migration. Visto en el primer post sobre apuntes Rails, ActiveRecord provee las siguientes características:

  • Independencia de la base de datos.
  • Funcionalidad CRUD.
  • Capacidades avanzadas para buscar.
  • Relaciones entre modelos.

Una de las primeras cosas que aprendí sobre las migraciones de Rails fue que tenían su propio método de versionado. ActiveRecord lleva la cuenta de las migraciones que se han ejecutado y las actualizaciones al esquema de la base de datos.

Si escribimos las migraciones en Ruby (aunque podemos usar texto SQL puro que es más dependiente del motor que se use), Rails se encarga de hacer las transformaciones correspondientes de sintaxis en cada caso.

Una migración básica se ve así:

class Product < ActiveRecord::Migration
  def up
    create_table :products do |t|
      t.string  :name
      t.integer :quantity
      t.timestamps
    end
  end
 
  def down
    drop_table :products
  end
end

El método up define lo que se va a hacer cuando se ejecute la migración, y down define el rollback. En este caso se va a crear una tabla products con las columnas name (string) y quantity (integer). Por defecto, ActiveRecord genera una columna id (esta se puede personalizar).

t.timestamps genera dos columnas: created_at y updated_at. Estas columnas se completan automáticamente por ActiveRecord con los tiempos de creación y actualización.

Podemos usar execute para ejecutar SQL arbitrario.

Las migraciones se encuentran en el directorio db/migrate del proyecto Rails, y su formato de nombre de archivo es:
TIMESTAMP_nombre_de_la_migracion.rb
El timestamp es un identificador, solía ser un número.

Buena práctica: No editar migraciones, escribir una nueva que ejecute los cambios necesarios.

Tipos soportados:
:binary, :boolean, :date, :datetime, :decimal, :float, :integer, :primary_key, :string, :text, :time, :timestamp

Métodos de migraciones:
add_column, add_index, change_column, change_table, drop_table, remove_column, remove_index, rename_column

Crear un modelo y su migración:
rails generate model Clase atributo:tipo atributo:tipo

Crear una migración vacía:
rails generate migration AddColumnToTable

El formato AddXXXtoYYY o RemoveXXXFromYYY en el nombre de la migración hace que se genere la declaración add/remove_column correspondiente:
rails generate migration AddPartNumberToProducts part_number:String

En la migración:
create_table :products do |t|
El objecto se pasa a un bloque permitiéndonos crear columnas en la tabla:
t.string :name, null: false
Por defecto el campo id es la clave primaria, pero podemos cambiarle el nombre con el parámetro :primary_key. Con id: false, podemos definir que no se genere un ID para nuestro modelo.

Dejo por acá esta primera entrega sobre Migraciones. Quedaría ver un poco más y algo que quedó pendiente del post pasado de Controladores para terminar con ese tema. Espero sus comentarios sobre los apuntes.

4 comentarios en este post

Feed de comentarios
  1. Avatar

    Armando 23 octubre. 2012 - 12:30

    Gracias por el tema. Lo hice pero al ejecutar la migracion me da el error “can´t convert Fixnum into string”, no lo entiendo porque los campos que le di eran string. “rails g model banco codigo:string nombre:string” y luego “rake db:migrate”
    Me puede orientar ???

    • Avatar

      Fernando 24 octubre. 2012 - 10:17

      Armando,
      Debe ser un tema de configuración o algo, a lo mejor

      Tu código tal cual está funciona:

      fernando@endor ~/workspace/picandocodigo/test_app $ rails g model banco codigo:string nombre:string
            invoke  active_record
            create    db/migrate/20121024131336_create_bancos.rb
            create    app/models/banco.rb
            invoke    test_unit
            create      test/unit/banco_test.rb
            create      test/fixtures/bancos.yml
      fernando@endor ~/workspace/picandocodigo/test_app $ rake db:migrate
      ==  CreateBancos: migrating ===================================================
      -- create_table(:bancos)
         -> 0.0008s
      ==  CreateBancos: migrated (0.0008s) ==========================================

      Cualquier cosa podés preguntar en RubySur que te pueden dar más información.

      Saludos!

Dejar un comentario

Toasty!