¿Cómo puedo cambiar el nombre de una columna de la base de datos en una migración de Ruby on Rails?
Nombré erróneamente una columna hased_password
en lugar de hashed_password
.
¿Cómo actualizo el esquema de la base de datos, usando migración para cambiar el nombre de esta columna?
25 answers
rename_column :table, :old_column, :new_column
Actualización:
Probablemente quieras crear una migración separada para hacer esto. (Cambia el nombre de FixColumnName como quieras)
script/generate migration FixColumnName
# creates db/migrate/xxxxxxxxxx_fix_column_name.rb
Luego edita la migración para hacer tu voluntad.
# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
def self.up
rename_column :table_name, :old_column, :new_column
end
def self.down
# rename back if you need or do something else or do nothing
end
end
Una actualización para Rails 3.1
Mientras que, los métodos up
y down
siguen siendo aplicables. Rails 3.1 recibe un método change
que " sabe cómo migrar su base de datos y revertirla cuando la migración se revierte sin la necesidad de escribir un método descendente separado "
rails g migration FixColumnName
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Si tiene un montón de columnas para cambiar el nombre, o algo que habría requerido repetir el nombre de la tabla una y otra vez.
rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...
Podrías usar change_table
para mantener las cosas un poco más ordenadas.
class FixColumnNames < ActiveRecord::Migration
def change
change_table :table_name do |t|
t.rename :old_column1, :new_column1
t.rename :old_column2, :new_column2
...
end
end
end
Gracias, Luke
&& Turadg
, por sacar el tema.
Entonces solo db:migrate
como de costumbre o como quiera que vaya con sus negocios.
Una actualización para Rails 4
Al crear un Migration
para cambiar el nombre de una columna, Rails 4 genera un método change
en lugar de up
y down
como se mencionó en la respuesta anterior. El método generado change
es el siguiente:
$ > rails g migration ChangeColumnName
Que creará un archivo de migración similar a este :
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-04 19:18:33
IMO, en este caso, mejor uso rake db:rollback
. A continuación, edite su migración y vuelva a escribir rake db:migrate
. Sin embargo, si tiene datos en la columna que no desea perder, use rename_column
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 21:51:09
Http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
Bajo Available Transformations
rename_column(table_name, column_name, new_column_name):
Cambia el nombre de una columna pero mantiene el tipo y el contenido.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-07 11:34:54
Si la columna ya está poblada con datos y vive en producción, recomendaría un enfoque paso a paso, para evitar el tiempo de inactividad en producción mientras espera las migraciones.
Primero crearía una migración de base de datos para agregar columnas con el(los) nuevo (s) nombre (s) y rellenarlas con los valores del antiguo nombre de columna.
class AddCorrectColumnNames < ActiveRecord::Migration
def up
add_column :table, :correct_name_column_one, :string
add_column :table, :correct_name_column_two, :string
puts 'Updating correctly named columns'
execute "UPDATE table_name SET correct_name_column_one = old_name_column_one, correct_name_column_two = old_name_column_two"
end
end
def down
remove_column :table, :correct_name_column_one
remove_column :table, :correct_name_column_two
end
end
Entonces confirmaría solo ese cambio, y empujaría el cambio a producción.
git commit -m 'adding columns with correct name'
Entonces, una vez que el commit ha sido empujado a la producción, yo ejecutar.
Production $ bundle exec rake db:migrate
Luego actualizaría todas las vistas/controladores que hacían referencia al antiguo nombre de columna al nuevo nombre de columna. Ejecutar a través de mi conjunto de pruebas, y confirmar solo esos cambios. (Después de asegurarse de que estaba trabajando localmente y pasar todas las pruebas primero!)
git commit -m 'using correct column name instead of old stinky bad column name'
Entonces yo empujaría ese compromiso a la producción.
En este punto, puede eliminar la columna original sin preocuparse por ningún tipo de tiempo de inactividad asociado con la migración en sí.
class RemoveBadColumnNames < ActiveRecord::Migration
def up
remove_column :table, :old_name_column_one
remove_column :table, :old_name_column_two
end
def down
add_column :table, :old_name_column_one, :string
add_column :table, :old_name_column_two, :string
end
end
Luego presione esto última migración a producción y ejecutar bundle exec rake db:migrate
en segundo plano.
Me doy cuenta de que esto está un poco más involucrado en un proceso, pero prefiero hacer esto que tener problemas con mi migración de producción.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-14 02:01:38
Ejecute el siguiente comando para crear un archivo de migración:
rails g migration ChangeHasedPasswordToHashedPassword
Luego, en el archivo generado en la carpeta db/migrate
, escriba rename_column
de la siguiente manera:
class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 21:56:42
De API:
rename_column(table_name, column_name, new_column_name)
Cambia el nombre de una columna pero mantiene el tipo y el contenido sigue siendo el mismo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-10 13:01:24
Algunas versiones de Ruby on Rails soportan el método up / down a la migración y si tienes el método up/down en tu migración, entonces:
def up
rename_column :table_name, :column_old_name, :column_new_name
end
def down
rename_column :table_name, :column_new_name, :column_old_name
end
Si tiene el método change
en su migración, entonces:
def change
rename_column :table_name, :column_old_name, :column_new_name
end
Para más información puede mover: Ruby on Rails - Migraciones o Registro Activo de las Migraciones.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 21:54:00
Si su código no se comparte con otro, entonces la mejor opción es hacer solo rake db:rollback
a continuación, edite el nombre de su columna en migración y rake db:migrate
. Eso es todo
Y puede escribir otra migración para cambiar el nombre de la columna
def change
rename_column :table_name, :old_name, :new_name
end
Eso es todo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-04 14:34:30
Si necesita cambiar los nombres de las columnas, deberá crear un marcador de posición para evitar un error de nombre de columna duplicado. He aquí un ejemplo:
class SwitchColumns < ActiveRecord::Migration
def change
rename_column :column_name, :x, :holder
rename_column :column_name, :y, :x
rename_column :column_name, :holder, :y
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-09 14:25:51
Como opción alternativa, si no estás casado con la idea de las migraciones, hay una gema atractiva para ActiveRecord que manejará los cambios de nombre automáticamente por ti, estilo Datamapper. Todo lo que hace es cambiar el nombre de la columna en su modelo (y asegúrese de poner Modelo.auto_upgrade! en la parte inferior de su modelo.rb) y viola! La base de datos se actualiza sobre la marcha.
Https://github.com/DAddYE/mini_record
Nota: Usted tendrá que nuke db/schema.rb para prevenir conflictos
Todavía en fases beta y obviamente no para todos, pero sigue siendo una opción convincente (actualmente lo estoy usando en dos aplicaciones de producción no triviales sin problemas)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-12 13:57:26
Si los datos actuales no son importantes para usted, simplemente puede eliminar su migración original utilizando:
rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'
Sin las comillas, luego realice cambios en la migración original y ejecute la migración ascendente de nuevo:
rake db:migrate
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 21:51:47
Simplemente cree una nueva migración, y en un bloque, use rename_column
como se muestra a continuación.
rename_column :your_table_name, :hased_password, :hashed_password
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 21:55:06
Para Ruby on Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 21:57:01
Manualmente podemos usar el siguiente método:
Podemos editar la migración manualmente como:
Abierto
app/db/migrate/xxxxxxxxx_migration_file.rb
Actualizar
hased_password
ahashed_password
-
Ejecute el siguiente comando
$> rake db:migrate:down VERSION=xxxxxxxxx
Entonces eliminará su migración:
$> rake db:migrate:up VERSION=xxxxxxxxx
Agregará su migración con el cambio actualizado.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 21:56:04
Generar el archivo de migración:
rails g migration FixName
# Crea db / migrate / xxxxxxxxxx.rb
Edite la migración para hacer su voluntad.
class FixName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 21:59:36
$: rails g migration RenameHashedPasswordColumn
invoke active_record
create db/migrate/20160323054656_rename_hashed_password_column.rb
Abra ese archivo de migración y modifique ese archivo como se muestra a continuación(Ingrese su original table_name
)
class RenameHashedPasswordColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-23 05:49:28
Ejecuta rails g migration ChangesNameInUsers
(o como quieras llamarlo)
Abra el archivo de migración que se acaba de generar y agregue esta línea en el método (entre def change
y end
):
rename_column :table_name, :the_name_you_want_to_change, :the_new_name
Guarde el archivo y ejecute rake db:migrate
en la consola
Echa un vistazo a tu schema.db
para ver si el nombre ha cambiado realmente en la base de datos!
Espero que esto ayude:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-23 16:10:36
Generar una migración de Ruby on Rails :
$:> rails g migration Fixcolumnname
Insertar código en el archivo de migración (XXXXXfixcolumnname.po):
class Fixcolumnname < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 22:00:14
def change
rename_column :table_name, :old_column_name, :new_column_name
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-08 18:01:21
Abre tu consola de Ruby on Rails e introduce:
ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-03 21:58:51
Tienes dos maneras de hacer esto:
-
En este tipo se ejecuta automáticamente el código inverso de la misma, cuando rollback.
def change rename_column :table_name, :old_column_name, :new_column_name end
-
Para este tipo, ejecuta el método up cuando
rake db:migrate
y ejecuta el método down cuandorake db:rollback
:def self.up rename_column :table_name, :old_column_name, :new_column_name end def self.down rename_column :table_name,:new_column_name,:old_column_name end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-05 05:10:58
Estoy en rails 5.2, y tratando de cambiar el nombre de una columna en un usuario de devise.
El bit rename_column
funcionó para mí, pero el singular :table_name
arrojó un error de "Tabla de usuarios no encontrada". Plural funcionó para mí.
rails g RenameAgentinUser
Luego cambie el archivo de migración a esto:
rename_column :users, :agent?, :agent
Donde :agente? es el antiguo nombre de la columna.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-06 13:42:53
Simplemente genere la migración usando el comando
rails g migration rename_hased_password
Después de eso, edite la migración, agregue la siguiente línea en el método de cambio
rename_column :table, :hased_password, :hashed_password
Esto debería hacer el truco.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-05 12:02:57
Cambios en la migración de Rails 5
Eg:
Rails g model Student student_name:string age: integer
Si desea cambiar la columna student_name como name
Nota: - si no ejecuta rails db: migrar
Puede hacer los siguientes pasos
Rails d model Student student_name:string age: integer
Esto eliminará el archivo de migración generado, ahora puede corregir el nombre de su columna
Rails g model Nombre del estudiante: string edad: integer
Si ha migrado (rails db: migrate), siga las opciones para cambiar el nombre de la columna
Rails g migration RemoveStudentNameFromStudent student_name: string
Rails g migration AddNameToStudent name: string
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-20 12:08:30
Update - Un primo cercano de create_table es change_table, usado para cambiar tablas existentes. Se usa de manera similar a create_table pero el objeto cedido al bloque sabe más trucos. Por ejemplo:
class ChangeBadColumnNames < ActiveRecord::Migration
def change
change_table :your_table_name do |t|
t.rename :old_column_name, :new_column_name
end
end
end
Esta manera es más eficiente si lo hacemos con otros métodos alterados como: remove / add index/remove index / add column, por ejemplo, podemos hacer más como:
# Rename
t.rename :old_column_name, :new_column_name
# Add column
t.string :new_column
# Remove column
t.remove :removing_column
# Index column
t.index :indexing_column
#...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-21 05:32:00