Ruby on Rails
Migraciones ActiveRecord
Buscar..
Parámetros
Tipo de columna | Descripción |
---|---|
:primary_key | Clave primaria |
:string | Cadena de datos más corta. Permite la opción de limit para el número máximo de caracteres. |
:text | Mayor cantidad de texto. Permite la opción de limit para el número máximo de bytes. |
:integer | Entero. Permite la opción de limit para el número máximo de bytes. |
:bigint | Entero mayor |
:float | Flotador |
:decimal | Número decimal con precisión variable. Permite opciones de precision y scale . |
:numeric | Permite opciones de precision y scale . |
:datetime | Objeto DateTime para fechas / horas. |
:time | Objeto de tiempo por tiempos. |
:date | Objeto de fecha para las fechas. |
:binary | Datos binarios. Permite la opción de limit para el número máximo de bytes. |
:boolean | Booleano |
Observaciones
La mayoría de los archivos de migración viven en
db/migrate/
directoriodb/migrate/
. Están identificados por una marca de tiempo UTC al principio de su nombre de archivo:YYYYMMDDHHMMSS_create_products.rb
.El comando de
rails generate
se puede acortar arails g
.Si a
:type
no se pasa a un campo, por defecto es una cadena.
Ejecutar migración específica
Para ejecutar una migración específica hacia arriba o hacia abajo, use db:migrate:up
o db:migrate:down
.
Hasta una migración específica:
rake db:migrate:up VERSION=20090408054555
rails db:migrate:up VERSION=20090408054555
Abajo una migración específica:
rake db:migrate:down VERSION=20090408054555
rails db:migrate:down VERSION=20090408054555
El número de versión en los comandos anteriores es el prefijo numérico en el nombre de archivo de la migración. Por ejemplo, para migrar a la migración 20160515085959_add_name_to_users.rb
, usaría 20160515085959
como número de versión.
Crear una tabla de unión
Para crear una tabla de unión entre students
y courses
, ejecute el comando:
$ rails g migration CreateJoinTableStudentCourse student course
Esto generará la siguiente migración:
class CreateJoinTableStudentCourse < ActiveRecord::Migration[5.0]
def change
create_join_table :students, :courses do |t|
# t.index [:student_id, :course_id]
# t.index [:course_id, :student_id]
end
end
end
Ejecución de migraciones en diferentes entornos.
Para ejecutar migraciones en el entorno de test
, ejecute este comando de shell:
rake db:migrate RAILS_ENV=test
Comenzando en Rails 5.0, puedes usar rails
lugar de rake
:
rails db:migrate RAILS_ENV=test
Agregar una nueva columna a una tabla
Para agregar un nuevo name
columna a la tabla de users
, ejecute el comando:
rails generate migration AddNameToUsers name
Esto genera la siguiente migración:
class AddNameToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :name, :string
end
end
Cuando el nombre de la migración tiene el formato AddXXXToTABLE_NAME
seguido de una lista de columnas con tipos de datos, la migración generada contendrá las declaraciones add_column
apropiadas.
Añadir una nueva columna con un índice.
Para agregar un nuevo email
columna indexada a la tabla de users
, ejecute el comando:
rails generate migration AddEmailToUsers email:string:index
Esto generará la siguiente migración:
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :email, :string
add_index :users, :email
end
end
Eliminar una columna existente de una tabla
Para eliminar el name
columna existente de la tabla de users
, ejecute el comando:
rails generate migration RemoveNameFromUsers name:string
Esto generará la siguiente migración:
class RemoveNameFromUsers < ActiveRecord::Migration[5.0]
def change
remove_column :users, :name, :string
end
end
Cuando el nombre de la migración tiene el formato RemoveXXXFromYYY
seguido de una lista de columnas con tipos de datos, la migración generada contendrá las declaraciones de remove_column
apropiadas.
Si bien no es necesario especificar el tipo de datos (por ejemplo, :string
) como parámetro para remove_column
, es altamente recomendable. Si no se especifica el tipo de datos, la migración no será reversible.
Agregar una columna de referencia a una tabla
Para agregar una referencia a un team
en la tabla de users
, ejecute este comando:
$ rails generate migration AddTeamRefToUsers team:references
Esto genera la siguiente migración:
class AddTeamRefToUsers < ActiveRecord::Migration[5.0]
def change
add_reference :users, :team, foreign_key: true
end
end
Esa migración creará una columna team_id
en la tabla de users
.
Si desea agregar un index
apropiado y la foreign_key
en la columna agregada, cambie el comando para que los rails generate migration AddTeamRefToUsers team:references:index
. Esto generará la siguiente migración:
class AddTeamRefToUsers < ActiveRecord::Migration
def change
add_reference :users, :team, index: true
add_foreign_key :users, :teams
end
end
Si desea asignar un nombre a su columna de referencia que no sea la que Rails genera automáticamente, agregue lo siguiente a su migración: (Por ejemplo, puede llamar al User
que creó la Post
como Author
en la tabla de Post
)
class AddAuthorRefToPosts < ActiveRecord::Migration
def change
add_reference :posts, :author, references: :users, index: true
end
end
Crear una nueva tabla
Para crear una nueva tabla de users
con el name
y el salary
las columnas, ejecute el comando:
rails generate migration CreateUsers name:string salary:decimal
Esto generará la siguiente migración:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.decimal :salary
end
end
end
Cuando el nombre de la migración tiene el formato CreateXXX
seguido de una lista de columnas con tipos de datos, se generará una migración que crea la tabla XXX
con las columnas enumeradas.
Añadiendo múltiples columnas a una tabla
Para agregar varias columnas a una tabla, separe el field:type
pares con espacios cuando use rails generate migration
comando de rails generate migration
.
La sintaxis general es:
rails generate migration NAME [field[:type][:index] field[:type][:index]] [options]
Por ejemplo, lo siguiente agregará los campos de name
, salary
y email
a la tabla de users
:
rails generate migration AddDetailsToUsers name:string salary:decimal email:string
Lo que genera la siguiente migración:
class AddDetailsToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :name, :string
add_column :users, :salary, :decimal
add_column :users, :email, :string
end
end
Ejecutando migraciones
Ejecutar comando:
rake db:migrate
rails db:migrate
La especificación de la versión de destino ejecutará las migraciones necesarias (arriba, abajo, cambiar) hasta que haya alcanzado la versión especificada. Aquí, el version number
es el prefijo numérico en el nombre de archivo de la migración.
rake db:migrate VERSION=20080906120000
rails db:migrate VERSION=20080906120000
Migraciones de retroceso
Para rollback
la migración más reciente, ya sea revirtiendo el método de change
o ejecutando el método down
. Ejecutar comando:
rake db:rollback
rails db:rollback
Deshacer las últimas 3 migraciones
rake db:rollback STEP=3
rails db:rollback STEP=3
STEP
proporcionar el número de migraciones para revertir.
Deshacer todas las migraciones
rake db:rollback VERSION=0
rails db:rollback VERSION=0
Mesas cambiantes
Si ha creado una tabla con algún esquema incorrecto, la forma más fácil de cambiar las columnas y sus propiedades es change_table
. Revise el siguiente ejemplo:
change_table :orders do |t|
t.remove :ordered_at # removes column ordered_at
t.string :skew_number # adds a new column
t.index :skew_number #creates an index
t.rename :location, :state #renames location column to state
end
La migración anterior cambia una tabla de orders
. Aquí hay una descripción línea por línea de los cambios:
-
t.remove :ordered_at
elimina la columnaordered_at
de lasorders
de la tabla. -
t.string :skew_number
agrega una nueva columna de tipo cadena llamadaskew_number
en la tabla deorders
. -
t.index :skew_number
agrega un índice en la columnaskew_number
en la tabla deorders
. -
t.rename :location, :state
cambia el nombre de la columna delocation
en la tabla deorders
astate
.
Agregar una columna única a una tabla
Para agregar un nuevo email
columna única a los users
, ejecute el siguiente comando:
rails generate migration AddEmailToUsers email:string:uniq
Esto creará la siguiente migración:
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :email, :string
add_index :users, :email, unique: true
end
end
Cambiar el tipo de una columna existente
Para modificar una columna existente en Rails con una migración, ejecute el siguiente comando:
rails g migration change_column_in_table
Esto creará un nuevo archivo de db/migration
directorio db/migration
(si aún no existe), que contendrá el archivo con el prefijo con la marca de tiempo y el nombre del archivo de migración que contiene el contenido a continuación:
def change
change_column(:table_name, :column_name, :new_type)
end
Guía de rieles - Cambio de columnas
Un método más largo pero más seguro.
El código anterior evita que el usuario pueda revertir la migración. Puede evitar este problema dividiendo el método de change
en métodos separados hacia up
y down
:
def up
change_column :my_table, :my_column, :new_type
end
def down
change_column :my_table, :my_column, :old_type
end
Rehacer migraciones
Puede revertir y luego migrar nuevamente usando el comando redo
. Básicamente, se trata de un acceso directo que combina las tareas de rollback
y migrate
.
Ejecutar comando:
rake db:migrate:redo
rails db:migrate:redo
Puede usar el parámetro STEP
para retroceder más de una versión.
Por ejemplo, para retroceder 3 migraciones:
rake db:migrate:redo STEP=3
rails db:migrate:redo STEP=3
Añadir columna con valor por defecto
El siguiente ejemplo agrega una columna admin
a la tabla de users
y le da a esa columna el valor predeterminado false
.
class AddDetailsToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :admin, :boolean, default: false
end
end
Las migraciones con valores predeterminados pueden tardar mucho tiempo en tablas grandes, por ejemplo, con PostgreSQL. Esto se debe a que cada fila deberá actualizarse con el valor predeterminado para la columna recién agregada. Para evitar esto (y reducir el tiempo de inactividad durante las implementaciones), puede dividir su migración en tres pasos:
- Agregue un
add_column
-migration similar al anterior, pero no establezca ningún valor predeterminado - Implemente y actualice la columna en una tarea de rake o en la consola mientras se ejecuta su aplicación. Asegúrese de que su aplicación ya escribe datos en esa columna para las filas nuevas / actualizadas.
- Agregue otra migración de
change_column
, que luego cambia el valor predeterminado de esa columna al valor predeterminado deseado
Prohibir valores nulos
Para prohibir null
valores null
en las columnas de su tabla, agregue el parámetro :null
a su migración, como esto:
class AddPriceToProducts < ActiveRecord::Migration
def change
add_column :products, :float, null: false
end
end
Comprobando el estado de la migración
Podemos comprobar el estado de las migraciones ejecutando.
rake db:migrate:status
rails db:migrate:status
La salida se verá así:
Status Migration ID Migration Name
--------------------------------------------------
up 20140711185212 Create documentation pages
up 20140724111844 Create nifty attachments table
up 20140724114255 Create documentation screenshots
up 20160213170731 Create owners
up 20160218214551 Create users
up 20160221162159 ********** NO FILE **********
up 20160222231219 ********** NO FILE **********
Bajo el campo de estado, up
significa que la migración se ha ejecutado y down
significa que necesitamos ejecutar la migración.
Crear una columna hstore
Hstore
columnas de Hstore
pueden ser útiles para almacenar configuraciones. Están disponibles en las bases de datos PostgreSQL después de habilitar la extensión.
class CreatePages < ActiveRecord::Migration[5.0]
def change
create_table :pages do |t|
enable_extension 'hstore' unless extension_enabled?('hstore')
t.hstore :settings
t.timestamps
end
end
end
Añadir una referencia propia
Una auto referencia puede ser útil para construir un árbol jerárquico. Esto se puede lograr con add_reference
en una migración.
class AddParentPages < ActiveRecord::Migration[5.0]
def change
add_reference :pages, :pages
end
end
La columna de clave externa será pages_id
. Si desea decidir sobre el nombre de la columna de clave externa, primero debe crear la columna y luego agregar la referencia.
class AddParentPages < ActiveRecord::Migration[5.0]
def change
add_column :pages, :parent_id, :integer, null: true, index: true
add_foreign_key :pages, :pages, column: :parent_id
end
end
Crear una columna de matriz
PostgreSQL admite una columna de array
. Rails convertirá automáticamente una matriz PostgreSQL en una matriz Ruby, y viceversa.
Crear una tabla con una columna de array
:
create_table :products do |t|
t.string :name
t.text :colors, array: true, default: []
end
Agregue una columna de array
a una tabla existente:
add_column :products, :colors, array: true, default: []
Agregue un índice para una columna de array
:
add_index :products, :colors, using: 'gin'
Agregar una restricción NOT NULL a los datos existentes
Supongamos que desea agregar una clave externa company_id
a la tabla de users
y desea tener una restricción NOT NULL
en ella. Si ya tiene datos en los users
, tendrá que hacerlo en varios pasos.
class AddCompanyIdToUsers < ActiveRecord::Migration
def up
# add the column with NULL allowed
add_column :users, :company_id, :integer
# make sure every row has a value
User.find_each do |user|
# find the appropriate company record for the user
# according to your business logic
company = Company.first
user.update!(company_id: company.id)
end
# add NOT NULL constraint
change_column_null :users, :company_id, false
end
# Migrations that manipulate data must use up/down instead of change
def down
remove_column :users, :company_id
end
end