ActiveRecord - Migraciones
Las migraciones nos permiten hacer cambios sobre el esquema de la base de datos de forma iterativa y consistente.
Una migración es un archivo que se crea dentro de la carpeta
db/migrate
y que contiene instrucciones para modificar el esquema de la base de datos (crear tablas, agregar columnas, eliminar columnas, eliminar tablas, etc.).Cuando creas un modelo desde la línea de comandos con el generador de Rails, automáticamente se crea una migración con las instrucciones para crear la tabla.
Sin embargo, también puedes crear migraciones desde cero (para agregar, remover o cambiar columnas de una tabla generalmente).
La forma más fácil de crear una migración es desde la línea de comandos:
$ rails generate migration <nombre_de_la_migración>
Por ejemplo, para crear una migración vacía y agregar un campo
published_at
a la tabla products
podemos ejecutar el siguiente comando:$ rails generate migration AddPublishedAtToProducts
El archivo que se generaría en
db/migrate
tendría lo siguiente:class AddPublishedAtToProducts < ActiveRecord::Migration[5.0]
def change
end
end
Si la migración es de la forma "AddXXXToYYY" seguido de una lista de columnas y su tipo, la migración va a tener las instrucciones para agregar ese o esos campos.
Por ejemplo, podemos agregar los campos
published
de tipo boolean
y published_at
de tipo datetime
de la siguiente forma:$ rails generate migration AddPublishedColumnsToProducts published:boolean published_at:datetime
Y eso va a generar la siguiente migración:
class AddPublishedColumnsToProducts < ActiveRecord::Migration[5.0]
def change
add_column :products, :published, :boolean
add_column :products, :published_at, :datetime
end
end
De forma similar podemos generar una migración para remover una columna si la migración es de la forma "RemoveXXXFromYYY":
$ rails generate migration RemovePublishedAtFromProducts published_at:datetime
Al ejecutar el comando generaría la siguiente migración:
class RemovePublishedAtFromProducts < ActiveRecord::Migration[5.0]
def change
remove_column :products, :published_at, :datetime
end
end
Por último, es posible generar una migración de una relación muchos a muchos entre dos tablas. por ejemplo:
$ rails generate migration CreateJoinTableCategoriesProducts categories products
Al ejecutar este comando se generaría la siguiente migración:
class CreateJoinTableCategoriesProducts < ActiveRecord::Migration[5.0]
def change
create_join_table :categories, :products do |t|
# t.index [:category_id, :product_id]
# t.index [:product_id, :category_id]
end
end
end
Ten en cuenta que esta es una tabla que representa la relación muchos a muchos entre dos tablas pero no tiene un modelo asociado.
Para ejecutar las migraciones pendientes ejecuta el siguiente comando en la consola:
$ rails db:migrate
Para reversar la última migración ejecuta el siguiente comando:
$ rails db:rollback
Para conocer el estado de las migraciones ejecuta:
$ rails db:migrate:status
Una migración no es más que una serie de instrucciones escritas en Ruby para modificar el esquema de la base de datos.
Las instrucciones se escriben en el método
change
de la migración.Las instrucciones más comunes son: agregar una columna, remover una columna, renombrar una columna y cambiar el tipo de una columna.
Utiliza el método
add_column
para agregar una columna. Como mínimo debes pasarle 3 argumentos: la tabla a la que quieres agregarle la columna, el nombre de la columna y el tipo de datos. Por ejemplo:add_column :products, :published, :boolean
add_column
recibe un cuarto argumento, un hash de opciones, allí puedes pasarle otras opciones, por ejemplo:add_column :products, :published, :boolean, default: false, null: false
add_column :products, :code, :string, limit: 50
Para agregar una columna que hace referencia a otra tabla utiliza
add_reference
. Por ejemplo:add_reference :products, :category, foreign_key: { on_delete: :cascade }
Utiliza el método
remove_column
pasándole los mismos argumentos que add_column
. Por ejemplo:remove_column :products, :published_at, :datetime
Utiliza el método
rename_column
para cambiar el nombre de una columna. Por ejemplo, para cambiar el nombre de la columna published_at
por published_date
:rename_columna :products, :published_at, :published_date
Para cambiar el tipo de datos y otras opciones utiliza el método
change_column
. Como mínimo debes pasarle el nombre de la tabla, el nombre de la columna y el nuevo tipo. Por ejemplo:change_column :products, :published_date, :date
change_column :products, :published, :string, limit: 80
Todos los métodos que hemos visto hasta ahora (
add_column
, remove_column
, etc.) son reversibles.Los métodos reversibles saben cómo volver a su estado anterior en caso de que se reverse la migración con
rails db:rollback
.Algunas migraciones pueden requerir un procesamiento complejo que Active Record no sabe cómo reversar.
Puedes utilizar el método
reversible
para escribir código que se va a ejecutar al migrar y reversar independientemente:class ExampleMigration < ActiveRecord::Migration[5.0]
def change
reversible do |dir|
dir.up do
puts "Esto se imprime cuando hacen la migración únicamente"
end
dir.down do
puts "Esto se imprime cuando reversan la migración únicamente"
end
end
end
end
El método
reversible
es útil para hacer migraciones de datos (p.e. cuando creas una nueva columna y debes actualizar todos los registros) o para ejecutar código SQL especial.Es posible que ahora no necesites esta funcionalidad pero es bueno que sepas que existe!
Last modified 4mo ago