web-dev-qa-db-fra.com

Comment renommer une colonne de base de données lors d'une migration Ruby on Rails?

J'ai nommé à tort 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?

1346
user1994764
rename_column :table, :old_column, :new_column

Mettre à jour:

Pour ce faire, vous souhaiterez probablement créer une migration distincte. (Renommez FixColumnName comme vous voulez)

script/generate migration FixColumnName
# creates  db/migrate/xxxxxxxxxx_fix_column_name.rb

Ensuite, éditez la migration pour faire votre volonté.

# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
  def self.up
    rename_column :table_name, :old_column, :new_column
  end

  def self.down
    # rename back if you need or do something else or do nothing
  end
end

Une mise à jour pour Rails 3.1

Alors que les méthodes up et down s'appliquent toujours. Rails 3.1 reçoit une méthode change qui "sait comment migrer votre base de données et l'inverser lorsque la migration est annulée sans qu'il soit nécessaire d'écrire une méthode down distincte"

Rails g migration FixColumnName

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

Si vous devez renommer un grand nombre de colonnes, ou quelque chose qui aurait nécessité la répétition répétée du nom de la table.

rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...

Vous pouvez utiliser change_table pour que les choses restent un peu plus propres.

class FixColumnNames < ActiveRecord::Migration
  def change
    change_table :table_name do |t|
      t.rename :old_column1, :new_column1
      t.rename :old_column2, :new_column2
      ...
    end
  end
end

_ {Merci, Luke && Turadg, d'avoir abordé le sujet.} _

Alors juste db:migrate comme d'habitude ou comme vous allez à votre entreprise.


Une mise à jour pour Rails 4

Lors de la création de Migration comme pour renommer une colonne, Rails 4 génère une méthode change au lieu de up et down, comme indiqué dans la réponse ci-dessus. La méthode change générée est la suivante: 

$ > Rails g migration ChangeColumnName

qui créera un fichier de migration similaire à celui-ci:

class ChangeColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
2167
nowk

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

67
elf.xf

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Sous Available Transformations

rename_column(table_name, column_name, new_column_name):

Renomme une colonne mais conserve le type et le contenu.

26
James Manning

Si la colonne est déjà remplie avec des données et en production, je recommanderais une approche pas à pas, afin d'éviter les temps morts en production pendant l'attente des migrations.

Premièrement, je créerais une migration de base de données pour ajouter des colonnes avec le ou les nouveaux noms et les renseigner 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

Ensuite, je commettrais uniquement ce changement et le transformerais en production.

git commit -m 'adding columns with correct name'

Ensuite, une fois que le commit a été mis en production, je me lance.

Production $ bundle exec rake db:migrate

Ensuite, je mettrais à jour tous les affichages/contrôleurs qui référencaient l'ancien nom de colonne au nouveau nom de colonne. Parcourez ma suite de tests et commettez uniquement ces modifications. (Après avoir vérifié que tout fonctionnait localement et réussi tous les tests en premier!)

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

Alors je pousserais cet engagement à la production. 

À ce stade, vous pouvez supprimer la colonne d'origine sans vous soucier des temps morts associés à 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 réalise que le processus est un peu plus complexe, mais je préfère le faire plutôt que de rencontrer des problèmes avec ma migration de production.

24
Paul Pettengill

Exécutez la commande ci-dessous pour créer un fichier de migration:

Rails g migration ChangeHasedPasswordToHashedPassword

Ensuite, dans le fichier généré dans le dossier db/migrate, écrivez rename_column comme ci-dessous:

class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
  def change
     rename_column :table_name, :hased_password, :hashed_password
  end
end
16
Shoaib Malik

De l'API:

rename_column(table_name, column_name, new_column_name)

Il renomme une colonne mais conserve le type et le contenu reste identique.

13
super_p

Certaines versions de Ruby on Rails prennent en charge la méthode de migration ascendante/descendante et si vous avez une méthode ascendante/descendante dans votre migration, alors:

def up
    rename_column :table_name, :column_old_name, :column_new_name
end

def down
    rename_column :table_name, :column_new_name, :column_old_name
end

Si vous avez la méthode change dans votre migration, alors:

def change
    rename_column :table_name, :column_old_name, :column_new_name
end

Pour plus d'informations, vous pouvez déplacer: Ruby on Rails - Migrations ou Migration d'enregistrements actifs.

12
uma

Si votre code n'est pas partagé avec un autre, la meilleure option consiste simplement à faire rake db:rollback.__ puis à modifier le nom de votre 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.

10
sunil

Si vous devez changer de nom de colonne, vous devez créer un espace réservé pour éviter une erreur de nom de colonne duplicate. Voici un exemple:

class SwitchColumns < ActiveRecord::Migration
  def change
    rename_column :column_name, :x, :holder
    rename_column :column_name, :y, :x
    rename_column :column_name, :holder, :y
  end
end
8
Abram

Si les données actuelles ne sont pas importantes pour vous, vous pouvez simplement supprimer votre migration d'origine en utilisant:

rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'

Sans les guillemets, apportez des modifications à la migration d'origine et réexécutez la migration de la manière suivante:

rake db:migrate
7
dirtydexter

Comme alternative, si vous n'êtes pas marié à l'idée de migrations, il existe une gemme convaincante pour ActiveRecord qui gérera automatiquement les changements de nom, à la manière de 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 modèle.rb) et de l'alto! La base de données est mise à jour à la volée. 

https://github.com/DAddYE/mini_record

Remarque: vous devrez neutraliser 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 aucun problème)

7
Steven Garcia

Pour Ruby on Rails 4:

def change
    rename_column :table_name, :column_name_old, :column_name_new
end
6
Hardik Hardiya

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
6
jon snow

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

Nous pouvons éditer la migration manuellement comme:

  • Ouvrez app/db/migrate/xxxxxxxxx_migration_file.rb

  • Mettre à jour hased_password à hashed_password

  • Exécuter la commande ci-dessous

    $> rake db:migrate:down VERSION=xxxxxxxxx
    

Ensuite, votre migration sera supprimée:

$> rake db:migrate:up VERSION=xxxxxxxxx

Il ajoutera votre migration avec le changement mis à jour.

5
Sumit Munot

Exécutez Rails g migration ChangesNameInUsers (ou le nom de votre choix)

Ouvrez le fichier de migration qui vient d'être généré et ajoutez cette ligne à 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 exécutez rake db:migrate dans la console.

Vérifiez 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 :)

4
Maddie

Génère le fichier de migration:

Rails g migration FixName

# Crée db/migrate/xxxxxxxxxx.rb

Modifiez la migration pour faire votre volonté.

class FixName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
4
vipin
$:  Rails g migration RenameHashedPasswordColumn
invoke  active_record
      create    db/migrate/20160323054656_rename_hashed_password_column.rb

Ouvrez ce fichier de migration et modifiez-le comme suit (saisissez votre table_name d'origine)

class  RenameHashedPasswordColumn < ActiveRecord::Migration
  def change
    rename_column :table_name, :hased_password, :hashed_password
  end
end
4
Prabhakar
 def change
    rename_column :table_name, :old_column_name, :new_column_name
  end
3
Apoorv

Générer une migration Ruby on Rails :

$:> Rails g migration Fixcolumnname

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

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

Vous avez deux façons de le faire:

  1. Dans ce type, il exécute automatiquement le code inverse de celui-ci, lors de la restauration.

    def change
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
  2. Pour ce type, il exécute la méthode up lorsque rake db:migrate et exécute la méthode down lorsque rake db:rollback:

    def self.up
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
    def self.down
      rename_column :table_name,:new_column_name,:old_column_name
    end
    
2
Sarwan Kumar

Ouvrez votre console Ruby on Rails et entrez:

ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
2
rinold simon

Je suis sur Rails 5.2 et j'essaie de renommer une colonne sur un utilisateur.

le bit rename_column a fonctionné pour moi, mais le singulier :table_name a généré une erreur "Table utilisateur non trouvée". Le pluriel a fonctionné pour moi.

Rails g RenameAgentinUser

Puis changez le fichier de migration en ceci:

rename_column :users, :agent?, :agent

Où: agent? est l'ancien nom de la colonne.

1
tomb

Let's KISS . Il suffit de trois étapes simples. Ce qui suit fonctionne pour Rails 5.2.

1 . Créer une migration

  • Rails g migration RenameNameToFullNameInStudents

  • Rails g RenameOldFieldToNewFieldInTableName - ainsi, les responsables de la base de code seront parfaitement au courant par la suite. (utilisez un pluriel pour le nom de la table).

2. Modifier la migration

# I prefer to explicitly write theupanddownmethods.

# ./db/migrate/20190114045137_rename_name_to_full_name_in_students.rb

class RenameNameToFullNameInStudents < ActiveRecord::Migration[5.2]
  def up
    # rename_column :table_name, :old_column, :new_column
    rename_column :students, :name, :full_name
  end

  def down
            # Note that the columns are reversed
    rename_column :students, :full_name, :name
  end
end

3. Exécutez vos migrations

rake db:migrate

Et vous partez pour les courses!

0
BKSpurgeon

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

Rails g migration rename_hased_password

Après cela, éditez la migration, ajoutez la ligne suivante dans la méthode de modification

rename_column :table, :hased_password, :hashed_password

Cela devrait faire l'affaire.

0
Ratnam Yadav

Changements de migration de Rails 5 

par exemple: 

Rails g model Student nom de l'étudiant: âge de la chaîne: entier

si vous voulez changer nom_étudiant column en nom

Remarque: - si vous n'exécutez pas Rails db: migrate

Vous pouvez faire les étapes suivantes 

Rails d model Student nom_étudiant: chaîne âge: entier

Cela supprimera le fichier de migration généré. Vous pouvez maintenant corriger le nom de votre colonne.

Rails g model Nom de l'étudiant: âge de la chaîne: entier

Si vous avez migré (Rails db: migrate), les options suivantes permettent de modifier le nom de la colonne.

Rails g migration RemoveStudentNameFromStudent nom_étudiant: chaîne

Rails g migration AddNameToStudent name: string

0
prasanthrubyist