¿Cómo se escribe una migración para cambiar el nombre de un modelo 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 utilizar una migración para cambiar el nombre de un modelo y su tabla correspondiente?
He aquí 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 y 4, ActiveRecord::Migration::CommandRecorder
sabe cómo revertir las migraciones de rename_table, así que puedes hacer esto:
class RenameOldTableToNewTable < ActiveRecord::Migration
def change
rename_table :old_table_name, :new_table_name
end
end
(Aún tienes que revisar y cambiar el nombre de tus archivos manualmente).
En Rails 4 todo lo que tenía que hacer era cambiar la definición.
def change
rename_table :old_table_name, :new_table_name
end
Y todos mis índices fueron atendidos por mí. No necesitaba actualizar manualmente los índices eliminando los antiguos y agregando otros nuevos.
Y también funciona usando el cambio para subir o bajar con respecto a los índices.
Las otras respuestas y comentarios cubrieron el cambio de nombre de tablas, el cambio de nombres de archivos y la revisión de su código.
Me gustaría agregar 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 Merchant y MerchantStat a Business y BusinessStat al mismo tiempo. De lo contrario, habría tenido que elegir demasiado al realizar la búsqueda y el reemplazo.
- Para cualquier otro modelo que dependa de su modelo mediante claves externas, los nombres de las columnas de clave externa de las otras tablas se derivarán del nombre de su modelo original. Por lo tanto, también querrás realizar algunas llamadas a 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 las relaciones normales has_one y has_many). De lo contrario, habría terminado con columnas como 'business_stat.merchant_id' apuntando a 'business.id'. Aquí hay una buena respuesta sobre cómo cambiar el nombre de las columnas.
- Al realizar búsquedas, recuerde buscar versiones singulares, plurales, en mayúscula, en minúsculas e incluso en MAYÚSCULAS (que pueden aparecer en los comentarios) de sus cadenas.
- Es mejor buscar primero las versiones en plural y luego en singular. De esa manera, si tiene un plural irregular, como en mi ejemplo de comerciantes :: negocios, puede obtener todos los plurales irregulares correctos. De lo contrario, puede terminar con, por ejemplo, "negocios" (3 s) como estado intermedio, lo que resultaría en aún más búsqueda y reemplazo.
- No reemplaces ciegamente cada ocurrencia. Si los nombres de sus modelos chocan con términos de programación comunes, con valores de otros modelos o con contenido textual en sus vistas, puede terminar siendo demasiado entusiasta. En mi ejemplo, quería cambiar el nombre de mi modelo a "Negocios" pero aún así referirme a ellos como "comerciantes" en el contenido de mi interfaz de usuario. 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.