Question Comment puis-je renommer une colonne de base de données dans une migration Ruby on Rails?


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?


1280
2018-01-02 16:18


origine


Réponses:


rename_column :table, :old_column, :new_column

Mettre à jour:

Vous souhaiterez probablement créer une migration distincte pour cela. (Renommez FixColumnName comme vous voulez)

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

Puis modifiez 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

Tandis que le up et down les méthodes s'appliquent toujours. Rails 3.1 reçoit un change méthode "sait comment migrer votre base de données et l'annuler lorsque la migration est annulée sans avoir besoin d'écrire une méthode séparée"

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 nécessité 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 propre.

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

Je vous remercie, Luke && Turadg, pour avoir soulevé le sujet.

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


Une mise à jour pour Rails 4

En créant un Migration comme pour renommer une colonne, Rails 4 génère un change méthode au lieu de up et down comme mentionné dans la réponse ci-dessus. Le généré change La méthode est comme ci-dessous:

$ > rails g migration ChangeColumnName

qui va créer un fichier de migration similaire à ceci:

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

2081
2018-01-02 16:31



OMI, dans ce cas, une meilleure utilisation rake db:rollback. Ensuite, modifiez 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.


65
2018-01-03 00:55



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

En dessous de Available Transformations

rename_column(table_name, column_name, new_column_name):

Renomme une colonne mais conserve le type et le contenu.


26
2018-01-02 16:26



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 l'exécution 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.


24
2017-08-30 22:08



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 db/migrate dossier, écrire rename_column comme ci-dessous:

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

16
2017-12-03 11:45



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.


13
2018-02-18 11:15



Certaines versions de Ruby on Rails prennent en charge la méthode ascendante / descendante pour la migration 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 le change méthode 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 Migrations d'enregistrements actifs.


12
2018-02-14 10:38



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 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
2017-12-04 14:34



Si vous devez changer de nom de colonne, vous devrez créer un espace réservé pour éviter erreur de nom de colonne en double. 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
2017-09-09 21:10



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 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 toujours un choix convaincant (je l'utilise actuellement dans deux applications de production non triviales sans problèmes)


7
2018-01-30 20:00