[ruby-on-rails] Comment puis-je renommer une colonne de base de données dans une migration Ruby on Rails?


11 Answers

IMO, dans ce cas, mieux utiliser rake db:rollback . Ensuite, éditez votre migration et tapez à nouveau rake db:migrate . Cependant, si vous avez des données dans la colonne que vous ne voulez pas perdre, utilisez rename_column .

Question

J'ai mal nommé une colonne hased_password au lieu de hashed_password .

Comment mettre à jour le schéma de base de données, en utilisant la migration pour renommer cette colonne?




Créez simplement une nouvelle migration, et dans un bloc, utilisez rename_column comme ci-dessous.

rename_column :your_table_name, :hased_password, :hashed_password



Générer une migration Ruby on Rails :

$:> rails g migration Fixcolumnname

Insérer le code dans le fichier de migration (XXXXXfixcolumnname.rb) :

class Fixcolumnname < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end



Ouvrez votre console Ruby on Rails et entrez:

ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column



Mise à jour - Un cousin proche de create_table est change_table, utilisé pour changer les tables existantes. Il est utilisé de la même manière que create_table mais l'objet cédé au bloc en sait plus. Par exemple:

class ChangeBadColumnNames < ActiveRecord::Migration
  def change
    change_table :your_table_name do |t|
      t.rename :old_column_name, :new_column_name
    end
  end
end

Cette méthode est plus efficace si nous utilisons d'autres méthodes telles que: supprimer / ajouter un index / supprimer un index / ajouter une colonne, par exemple, nous pouvons faire plus comme:

# Rename
t.rename :old_column_name, :new_column_name
# Add column
t.string :new_column
# Remove column
t.remove :removing_column
# Index column
t.index :indexing_column
#...



Comme option alternative, si vous n'êtes pas marié à l'idée de migrations, il y a une gemme convaincante pour ActiveRecord qui gérera les changements de nom automatiquement pour vous, style Datamapper. Tout ce que vous faites est de changer le nom de la colonne dans votre modèle (et assurez-vous de mettre Model.auto_upgrade! Au bas de votre model.rb) et l'alto! La base de données est mise à jour à la volée.

https://github.com/DAddYE/mini_record

Note: Vous aurez besoin de nuke db / schema.rb pour éviter les conflits

Toujours en phase bêta et évidemment pas pour tout le monde mais toujours un choix convaincant (je l'utilise actuellement dans deux applications de production non triviales sans problèmes)




De l'API:

rename_column(table_name, column_name, new_column_name)

Il renomme une colonne mais conserve le même type et le même contenu.




Run rails g migration ChangesNameInUsers (ou ce que vous voulez nommer)

Ouvrez le fichier de migration qui vient d'être généré et ajoutez cette ligne dans la méthode (entre def change et end ):

rename_column :table_name, :the_name_you_want_to_change, :the_new_name

Enregistrez le fichier et lancez rake db:migrate dans la console

Découvrez votre schema.db afin de voir si le nom a réellement changé dans la base de données!

J'espère que cela t'aides :)




Si votre code n'est pas partagé avec un autre, alors la meilleure option est de faire juste rake db:rollback puis éditez votre nom de colonne dans la migration et rake db:migrate . C'est tout

Et vous pouvez écrire une autre migration pour renommer la colonne

 def change
    rename_column :table_name, :old_name, :new_name
  end

C'est tout.




Si la colonne contient déjà des données et est en production, je recommande une approche étape par étape, afin d'éviter les temps d'arrêt en production en attendant les migrations.

D'abord je créerais une migration de DB pour ajouter des colonnes avec le nouveau nom (s) et les remplir avec les valeurs de l'ancien nom de colonne.

class AddCorrectColumnNames < ActiveRecord::Migration
  def up
    add_column :table, :correct_name_column_one, :string
    add_column :table, :correct_name_column_two, :string

    puts 'Updating correctly named columns'
    execute "UPDATE table_name SET correct_name_column_one = old_name_column_one, correct_name_column_two = old_name_column_two"
    end
  end

  def down
    remove_column :table, :correct_name_column_one
    remove_column :table, :correct_name_column_two
  end
end

Alors je commettrais juste ce changement, et pousserais le changement dans la production.

git commit -m 'adding columns with correct name'

Ensuite, une fois le commit mis en production, je courrais.

Production $ bundle exec rake db:migrate

Ensuite, je mettrais à jour toutes les vues / contrôleurs qui référencent l'ancien nom de colonne au nouveau nom de colonne. Exécuter ma suite de tests et valider uniquement ces modifications. (Après vous être assuré qu'il travaillait localement et passer tous les tests en premier!)

git commit -m 'using correct column name instead of old stinky bad column name'

Ensuite, je pousserais cet engagement à la production.

À ce stade, vous pouvez supprimer la colonne d'origine sans vous soucier de toute interruption associée à la migration elle-même.

class RemoveBadColumnNames < ActiveRecord::Migration
  def up
    remove_column :table, :old_name_column_one
    remove_column :table, :old_name_column_two
  end

  def down
    add_column :table, :old_name_column_one, :string
    add_column :table, :old_name_column_two, :string
  end
end

Poussez ensuite cette dernière migration vers la production et exécutez bundle exec rake db:migrate en arrière-plan.

Je me rends compte que c'est un peu plus impliqué dans un processus, mais je préfère le faire que d'avoir des problèmes avec ma migration de production.




Il suffit de générer la migration en utilisant la commande

rails g migration rename_hased_password

Après cette modification, la migration ajoute la ligne suivante dans la méthode de modification

rename_column :table, :hased_password, :hashed_password

Cela devrait faire l'affaire.




Manuellement, nous pouvons utiliser la méthode ci-dessous:

Nous pouvons éditer la migration manuellement comme:

  • Ouvrez app/db/migrate/xxxxxxxxx_migration_file.rb

  • Mise à jour de hased_password à hashed_password

  • Exécutez la commande ci-dessous

    $> rake db:migrate:down VERSION=xxxxxxxxx
    

Ensuite, il supprimera votre migration:

$> rake db:migrate:up VERSION=xxxxxxxxx

Il ajoutera votre migration avec le changement mis à jour.






Related