Comment puis-je renommer une colonne de base de données dans 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 la base de données, en utilisant migration pour renommer cette colonne?

1307
demandé sur Peter Mortensen 2010-01-02 19:18:42

25 réponses

rename_column :table, :old_column, :new_column

mise à jour:

vous voudrez probablement créer une migration séparée pour faire cela. (Renommer FixColumnName comme vous voulez)

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

puis éditez la migration pour faire votre testament.

# 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 les 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 de l'Inverser lorsque la migration est annulée sans avoir besoin d'écrire une méthode "

rails g migration FixColumnName

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

si vous avez un tas de colonnes à renommer, ou quelque chose qui aurait exigé de répéter le nom de la table encore et encore.

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

, Vous pourriez utiliser change_table pour garder les choses un peu plus soignée.

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 , pour avoir abordé le sujet.

puis juste db:migrate comme d'habitude ou comme vous allez sur vos affaires.


une mise à jour pour les Rails 4

tout en créant un Migration comme pour renommer une colonne, Rails 4 génère un Méthode change au lieu de up et down comme mentionné 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
2115
répondu nowk 2015-12-04 19:18:33

de l'OMI, dans ce cas, il vaut mieux utiliser rake db:rollback . Puis modifiez votre migration et tapez à nouveau rake db:migrate . Toutefois, si vous avez des données dans la colonne que vous ne voulez pas perdre, puis utiliser rename_column .

66
répondu elf.xf 2016-03-03 21:51:09

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
répondu James Manning 2014-02-07 11:34:54

si la colonne est déjà peuplée de données et vit en production, je recommande une approche pas à pas, afin d'éviter les temps d'arrêt en production en attendant les migrations.

d'abord je créerais une migration db pour ajouter des colonnes avec le(s) nouveau (S) nom (s) et les peupler 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 j'engagerais juste ce changement, et je pousserais le changement dans la production.

git commit -m 'adding columns with correct name'

une fois que l'engagement a été poussé dans la production, je courrais.

Production $ bundle exec rake db:migrate

puis je mettrais à jour toutes les vues/contrôleurs qui référencent l'ancien nom de colonne au nouveau nom de colonne. Parcourez ma suite de tests, et n'engagez que ces changements. (Après s'être assuré qu'il fonctionnait localement et avoir passé 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 point vous pouvez supprimer le colonne d'origine sans se soucier d'aucune sorte de temps d'arrêt associé à 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

puis pousser cette dernière migration vers la production et lancer bundle exec rake db:migrate en arrière-plan.

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

24
répondu Paul Pettengill 2013-09-14 02:01:38

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

rails g migration ChangeHasedPasswordToHashedPassword

puis 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
répondu Shoaib Malik 2016-03-03 21:56:42

de API:

rename_column(table_name, column_name, new_column_name)

il renomme une colonne mais garde le type et le contenu reste le même.

13
répondu super_p 2014-12-10 13:01:24

certaines versions de Ruby on Rails supportent la méthode up/down vers la migration et si vous avez la méthode up/down 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'information vous pouvez déplacer: Ruby on Rails - Migrations ou " migrations actives D'enregistrements .

12
répondu uma 2016-03-03 21:54:00

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

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

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

C'est ça.

10
répondu sunil 2013-12-04 14:34:30

si vous devez changer de nom de colonne, vous devez créer un paramètre pour éviter une erreur de nom de colonne dupliqué . 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
répondu Abram 2016-08-09 14:25:51

comme option alternative, si vous n'êtes pas marié à l'idée des migrations, il y a un petit bijou pour ActiveRecord qui gérera les changements de nom automatiquement pour vous, le style Datamapper. Tout ce que vous faites est de changer le nom de la colonne dans votre modèle (et assurez-vous de mettre modèle.auto_upgrade! au bas de votre modèle.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 prévenir les conflits

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

7
répondu Steven Garcia 2018-02-12 13:57:26

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, puis faire des changements dans la migration originale et relancer la migration par:

rake db:migrate
6
répondu dirtydexter 2016-03-03 21:51:47

crée simplement une nouvelle migration, et dans un bloc, utilise rename_column comme ci-dessous.

rename_column :your_table_name, :hased_password, :hashed_password
6
répondu jon snow 2016-03-03 21:55:06

pour Ruby sur Rails 4:

def change
    rename_column :table_name, :column_name_old, :column_name_new
end
6
répondu Hardik Hardiya 2016-03-03 21:57:01

manuellement nous pouvons utiliser la méthode suivante:

nous pouvons modifier la migration manuellement comme:

  • Ouvrir app/db/migrate/xxxxxxxxx_migration_file.rb

  • mise à Jour hased_password à hashed_password

  • , Exécutez la commande ci-dessous

    $> rake db:migrate:down VERSION=xxxxxxxxx
    

alors il supprimera votre migration:

$> rake db:migrate:up VERSION=xxxxxxxxx

il ajoutera votre migration avec la modification mise à jour.

5
répondu Sumit Munot 2016-03-03 21:56:04

génère le fichier de migration:

rails g migration FixName

# Crée db/migrate/xxxxxxxxxx.rb

éditez la migration pour faire votre testament.

class FixName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
4
répondu vipin 2016-03-03 21:59:36
$:  rails g migration RenameHashedPasswordColumn
invoke  active_record
      create    db/migrate/20160323054656_rename_hashed_password_column.rb

ouvrir ce fichier de migration et modifier ce fichier comme ci-dessous(entrer votre original table_name )

class  RenameHashedPasswordColumn < ActiveRecord::Migration
  def change
    rename_column :table_name, :hased_password, :hashed_password
  end
end
4
répondu Prabhakar 2016-03-23 05:49:28

Run rails g migration ChangesNameInUsers (ou quel que soit le nom que vous voulez lui donner)

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

rename_column :table_name, :the_name_you_want_to_change, :the_new_name

Enregistrer le fichier, et exécuter rake db:migrate dans la console

Vérifiez votre schema.db pour voir si le nom a effectivement changé dans la base de données!

Espérons que cela aide :)

4
répondu Maddie 2016-12-23 16:10:36

Generate a Ruby on Rails migration :

$:> rails g migration Fixcolumnname

inscrire 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
3
répondu vipin 2016-03-03 22:00:14
 def change
    rename_column :table_name, :old_column_name, :new_column_name
  end
3
répondu Apoorv 2017-06-08 18:01:21

ouvrez votre console Ruby on Rails et entrez:

ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
2
répondu rinold simon 2016-03-03 21:58:51

Vous avez deux façons de le faire:

  1. dans ce type, il exécute automatiquement le code inverse de celui-ci, lors du roll-back.

    def change
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
  2. à ce type, il exécute la méthode vers le haut quand rake db:migrate et exécute la méthode vers le bas quand 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
répondu Sarwan Kumar 2016-03-05 05:10:58

je suis sur des rails 5.2, et en essayant de renommer une colonne sur un dispositif Utilisateur.

le rename_column bit travaillé pour moi, mais le singulier :table_name jeté une" table D'Utilisateur pas trouvé " erreur. Pluriel a fonctionné pour moi.

rails g RenameAgentinUser

puis changer le fichier de migration à ceci:

rename_column :users, :agent?, :agent

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

1
répondu tomb 2018-09-06 13:42:53

juste générer la migration en utilisant la commande

rails g migration rename_hased_password

après cela modifier la migration ajouter la ligne suivante dans la méthode de changement

rename_column :table, :hased_password, :hashed_password

ça devrait faire l'affaire.

0
répondu Ratnam Yadav 2017-10-05 12:02:57

Rails 5 la migration des changements

par exemple:

rails g model Student_name: string age:integer

si vous voulez changer student_name colonne nom

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

vous pouvez faire les étapes suivantes""

rails d model Student_name: string age:integer

cela supprimera le fichier de migration généré, Maintenant vous pouvez corriger le nom de votre colonne

rails g Modèle Nom de l'élève: chaîne âge: entier

si vous avez migré (rails db: migrate), les options suivantes pour changer le nom de la colonne

rails g migration RemoveStudentNameFromStudent student_name: string

rails g migration AddNameToStudent nom: string

0
répondu prasanthrubyist 2017-12-20 12:08:30

Update - un cousin proche de create_table est change_table, utilisé pour changer les tables existantes. Il est utilisé de la même façon que create_table mais l'objet cédé au bloc connaît plus de trucs. 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 façon est plus efficace si nous faisons avec d'autres méthodes alter telles que: supprimer / ajouter index / supprimer index / ajouter colonne, eg 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
#...
-1
répondu Hieu Pham 2016-05-21 05:32:00