¿Cómo se escribe una migración para cambiar el nombre de un modelo ActiveRecord y su tabla en Rails?
-
19-08-2019 - |
Pregunta
Soy terrible para nombrar 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?
Solución
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 ir y cambiar el nombre del archivo de declaración del modelo manualmente.
Edición :
En Rails 3.1 & amp; 4, ActiveRecord :: Migration :: CommandRecorder
sabe cómo revertir 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
(Todavía tiene que pasar y cambiar manualmente el nombre de sus archivos).
Otros consejos
En Rails 4 todo lo que tenía que hacer era el cambio de definición
def change
rename_table :old_table_name, :new_table_name
end
Y todos mis índices se ocuparon de mí. No necesitaba actualizar manualmente los índices eliminando los antiguos y agregando nuevos.
Y funciona utilizando el cambio para subir o bajar en lo que respecta a los índices también.
Las otras respuestas y comentarios cubrieron el cambio de nombre de la tabla, el cambio de nombre de archivo y el grepping a través de su código.
Me gustaría agregar algunas advertencias más:
Usemos un ejemplo del mundo real que enfrenté hoy: cambiar el nombre de un modelo de 'Comerciante' a 'Negocio'.
- No olvide cambiar los nombres de 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 hacer demasiadas elecciones al realizar búsquedas y reemplazos.
- Para cualquier otro modelo que dependa de su modelo mediante claves externas, los nombres de columna de clave externa de las otras tablas se derivarán del nombre del modelo original. Por lo tanto, 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 unión (para la relación has_and_belongs_to_many) y otras tablas dependientes (para las relaciones has_one y has_many normales). 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 grepping, recuerda buscar en singular, plural, en mayúscula, versiones en minúsculas e incluso MAYÚSCULAS (que pueden aparecer en los comentarios) de tus cadenas.
- Es mejor buscar versiones en plural primero, luego en singular. Ese manera si tienes 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, 'negocios' (3 s) como estado intermedio, lo que resulta en aún más búsqueda y reemplazo.
- No reemplace ciegamente cada ocurrencia. Si los nombres de sus modelos chocan con términos de programación comunes, con valores en otros modelos, o con contenido textual en sus vistas, puede terminar siendo demasiado ansioso. En mi ejemplo, quería cambiar el nombre de mi modelo a 'Negocios' pero Todavía me refiero a ellos como 'comerciantes' en el contenido de mi interfaz de usuario. También tuve 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 llevó a cambiar el nombre del modelo en primer lugar.
También debe 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 lo describen otras respuestas aquí.
Ver: 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 atascas con una migración que intenta efectuar algo que ya no existe. Es mejor que descarte toda la base de datos y comience nuevamente si no puede retroceder. Tenga en cuenta que es posible que deba hacer una copia de seguridad de algo.
También: revise schema_db para ver cualquier nombre de columna relevante en otras tablas definidas por un has_ ??o belong_to o algo. Probablemente también necesite editarlos.
Y finalmente, hacer esto sin un conjunto de pruebas de regresión sería una locura.