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

StackOverflow https://stackoverflow.com/questions/471416

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?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top