¿Cómo se escribe una migración para renombrar un modelo de ActiveRecord y su tabla en Rails?


Soy terrible nombrando y me doy cuenta de que hay un mejor conjunto de nombres para mis modelos en mi aplicación Rails.
¿Hay alguna forma de usar una migración para cambiar el nombre de un modelo y su tabla correspondiente?

Author: user2262149, 2009-01-23

4 answers

Aquí hay un ejemplo:

class RenameOldTableToNewTable < ActiveRecord::Migration
  def self.up
    rename_table :old_table_name, :new_table_name
  end

  def self.down
    rename_table :new_table_name, :old_table_name
  end
end

Tuve que cambiar el nombre del archivo de declaración del modelo manualmente.

Editar:

En Rails 3.1 & 4, ActiveRecord::Migration::CommandRecorder sabe cómo invertir las migraciones rename_table, por lo que puede hacer esto:

class RenameOldTableToNewTable < ActiveRecord::Migration
  def change
    rename_table :old_table_name, :new_table_name
  end 
end

(Usted todavía tiene que ir a través y cambiar manualmente el nombre de sus archivos.)

 548
Author: Readonly,
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-11-17 07:01:58

En Rails 4 todo lo que tenía que hacer era el cambio def

def change
  rename_table :old_table_name, :new_table_name
end

Y todos mis índices fueron atendidos por mí. No necesité actualizar manualmente los índices eliminando los antiguos y agregando otros nuevos.

Y funciona usando el cambio para subir o bajar en lo que respecta a los índices también.

 60
Author: bfcoder,
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-17 01:27:55

Las otras respuestas y comentarios cubrieron el cambio de nombre de tabla, el cambio de nombre de archivo y el greping a través de su código.

Me gustaría añadir algunas advertencias más:

Usemos un ejemplo del mundo real al que me enfrenté hoy: cambiar el nombre de un modelo de 'Comerciante' a 'Negocio.'

  • No olvide cambiar los nombres de las tablas y modelos dependientes en la misma migración. Cambié mis modelos de Merchant y MerchantStat a Business y BusinesStat al mismo tiempo. De lo contrario, yo también habría tenido que hacerlo. mucha selección y elección al realizar búsquedas y reemplazos.
  • Para cualquier otro modelo que dependa de su modelo a través de claves foráneas, los nombres de columna de claves foráneas de las otras tablas se derivarán del nombre de su modelo original. Por lo que también querrá hacer algunas llamadas rename_column en estos modelos dependientes. Por ejemplo, tuve que cambiar el nombre de la columna' merchant_id ' a 'business_id' en varias tablas de combinación (para la relación has_and_belongs_to_many) y otras tablas dependientes (para has_one normal y has_many relaciones). De lo contrario habría terminado con columnas como 'business_stat.merchant_id ' apuntando a 'business.id'. Aquí hay una buena respuesta sobre hacer renombres de columna.
  • Al greping, recuerde buscar singular, plural, en mayúscula, versiones en minúsculas e incluso en mayúsculas (lo que puede ocurrir en los comentarios) de tus cuerdas.
  • Es mejor buscar las versiones en plural primero, luego en singular. Que manera si usted tiene un plural irregular-como en mis comerciantes :: ejemplo de negocios - puede obtener todos los plurales irregulares correctos. De lo contrario, puede terminar con, por ejemplo,' businesses ' (3 s) como un estado intermedio, lo que resulta en aún más búsqueda y reemplazo.
  • No reemplace ciegamente cada ocurrencia. Si los nombres de los modelos chocan con términos de programación comunes, con valores en otros modelos, o con contenido textual en sus puntos de vista, puede terminar siendo demasiado ansioso. En mi ejemplo, quería cambiar el nombre de mi modelo a 'Business' pero todavía se refieren a ellos como 'comerciantes' en el contenido de mi IU. También tenía un rol de "comerciante" para mis usuarios en CanCan - fue la confusión entre el rol de comerciante y el modelo de Comerciante lo que me hizo cambiar el nombre del modelo en primer lugar.
 43
Author: armchairdj,
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-05-23 10:31:39

También necesita reemplazar sus índices:

class RenameOldTableToNewTable< ActiveRecord:Migration
  def self.up
    remove_index :old_table_name, :column_name
    rename_table :old_table_name, :new_table_name
    add_index :new_table_name, :column_name
  end 

  def self.down
    remove_index :new_table_name, :column_name
    rename_table :new_table_name, :old_table_name
    add_index :old_table_name, :column_name
  end
end

Y cambie el nombre de sus archivos, etc., manualmente como otras respuestas describen aquí.

Véase: http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Asegúrese de que puede retroceder y avanzar después de escribir esta migración. Puede ser complicado si te equivocas y te quedas atascado con una migración que intenta afectar algo que ya no existe. Mejor basura toda la base de datos y empezar de nuevo si no puede retrocede. Así que ten en cuenta que es posible que necesites respaldar algo.

También: compruebe schema_db para cualquier nombre de columna relevante en otras tablas definidas por un has_ o belongs_to o algo así. Probablemente también necesites editarlos.

Y finalmente, hacer esto sin un conjunto de pruebas de regresión sería una locura.

 23
Author: Rimian,
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
2012-12-05 22:24:04