ruby-on-rails - migrations - rails migration not null
¿Cómo se escribe una migración para cambiar el nombre de un modelo ActiveRecord y su tabla en Rails? (4)
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?
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.
Editar:
En Rails 3.1 y 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
(Aún tiene que pasar y cambiar el nombre de sus archivos manualmente).
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 fueron atendidos por mí. No necesitaba actualizar manualmente los índices eliminando los antiguos y agregando los 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 archivos y el grep 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 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 demasiada 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 externas, los nombres de columna de clave externa de las otras tablas se derivarán de su nombre de modelo original. Así que también querrás 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 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 hacer renombrados de columnas.
- Cuando haga grep, recuerde buscar versiones singulares, plurales, en mayúsculas, minúsculas e incluso MAYÚSCULAS (que pueden aparecer en comentarios) de sus cadenas.
- Lo mejor es buscar primero versiones en plural, luego singular. De esa manera, si tiene un plural irregular, como en el ejemplo de mis comerciantes :: negocios, puede corregir todos los plurales irregulares. De lo contrario, puede terminar con, por ejemplo, ''businesss'' (3 s) como estado intermedio, lo que resultará en 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 aún así debería referirme 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 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 renombra tus archivos, etc. manualmente como lo describen otras respuestas aquí.
Consulte: 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 se equivoca y se atasca con una migración que intenta realizar algo que ya no existe. Mejor elimine la basura de toda la base de datos y comience de nuevo si no puede retroceder. Así que ten en cuenta que es posible que necesites hacer una copia de seguridad de algo.
También: verifique schema_db para ver si hay nombres de columnas relevantes en otras tablas definidas por has_ o belongs_to o algo así. Probablemente necesites editarlos también.
Y finalmente, hacer esto sin un conjunto de pruebas de regresión sería una locura.