Comment puis-je renommer une colonne de base de données dans une migration Ruby on Rails ?
-
22-09-2019 - |
Question
J'ai mal nommé une colonne hased_password
au lieu de hashed_password
.
Comment mettre à jour le schéma de la base de données en utilisant la migration pour renommer cette colonne ?
La solution
rename_column :table, :old_column, :new_column
Mise à jour:
Vous aurez probablement envie de créer une migration distincte pour le faire. (Renommer FixColumnName comme vous)
script/generate migration FixColumnName
# creates db/migrate/xxxxxxxxxx_fix_column_name.rb
Modifiez ensuite la migration pour faire ta 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 Rails 3.1
Alors que, les méthodes de up
et down
appliquent encore. Rails 3.1 reçoit une méthode change
que "sait comment migrer votre base de données et inverse quand la migration est annulée sans besoin d'écrire une méthode distincte vers le bas "
rails g migration FixColumnName
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Si vous arrive d'avoir 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 pouvez 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
Merci, Luke
&& Turadg
, pour aborder le sujet.
Ensuite, il suffit db:migrate
comme d'habitude ou mais vous allez sur votre entreprise.
Une mise à jour pour les rails 4
Lors de la création d'un Migration
comme pour renommer une colonne, des rails 4 génère une méthode de change
au lieu de up
et down
comme mentionné dans la réponse ci-dessus. La méthode de change
généré 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
Autres conseils
OMI, dans ce cas, une meilleure utilisation rake db:rollback
. Modifiez ensuite 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 utilisez rename_column
.
Si la colonne est déjà remplie avec des données et de vivre dans la production, je recommande une approche étape par étape, afin d'éviter les temps d'arrêt de la production en attendant les migrations.
D'abord, je crée une migration db pour ajouter des colonnes avec le nouveau nom (s) et les remplir avec les valeurs de l'ancien nom de la 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 commets tout ce changement, et pousser le changement dans la production.
git commit -m 'adding columns with correct name'
Ensuite, une fois la validation a été poussé dans la production, je courrais.
Production $ bundle exec rake db:migrate
Ensuite, je mets à jour toutes les vues / contrôleurs qui faisaient référence à l'ancien nom de colonne au nouveau nom de la colonne. Exécuter dans ma suite de tests, et engager seulement ces changements. (Après s'être assuré qu'il travaillait sur place et passer tous les tests d'abord!)
git commit -m 'using correct column name instead of old stinky bad column name'
Ensuite, je pousse que commettras à la production.
À ce stade, vous pouvez supprimer la colonne d'origine sans se soucier de toute sorte de temps d'arrêt 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
Ensuite, poussez cette dernière migration vers la production et la gestion bundle exec rake db:migrate
en arrière-plan.
Je sais que cela est un peu plus compliqué d'un processus, mais je préfère faire ce que d'avoir des problèmes avec ma migration de production.
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
Dans Available Transformations
rename_column(table_name, column_name, new_column_name):
renomme une colonne, mais maintient le type et le contenu.
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
De l'API:
rename_column(table_name, column_name, new_column_name)
Il renomme une colonne mais conserve le type et le contenu reste la même.
Certaines versions de Ruby on Rails prennent en charge la méthode haut / bas pour la migration et si vous avez méthode haut / bas dans votre migration, puis:
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, puis:
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 actifs Enregistrez Migration .
Si votre code n'est pas partagé avec un autre, alors la meilleure option est de le faire rake db:rollback
puis modifiez votre nom de colonne dans la migration et rake db:migrate
. Thats it
Et vous pouvez écrire une autre migration pour renommer la colonne
def change
rename_column :table_name, :old_name, :new_name
end
Thats it.
Si vous avez besoin de changer les noms de colonnes, vous devez créer un espace réservé pour éviter un nom de colonne en double Erreur . 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
En option alternative, si vous n'êtes pas marié à l'idée des migrations, il y a un petit bijou convaincant pour ActiveRecord qui se chargera de le nom change automatiquement pour vous, DataMapper style. Tout ce que vous faites est de changer le nom de la colonne dans votre modèle (et assurez-vous que vous mettez Model.auto_upgrade! au bas de votre model.rb) et alto! Base de données est mise à jour à la volée.
https://github.com/DAddYE/mini_record
Note: Vous aurez besoin de l'arme nucléaire db / schema.rb pour éviter les conflits
Toujours en phase bêta et évidemment pas pour tout le monde, mais encore un choix convaincant (je l'utilise actuellement dans deux applications de production non triviales sans problème)
Si les données actuelles ne sont pas important pour vous, il vous suffit de prendre 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 d'origine et exécuter la migration à nouveau par:
rake db:migrate
Il suffit de créer une nouvelle migration, et dans un bloc, utilisez rename_column
comme ci-dessous.
rename_column :your_table_name, :hased_password, :hashed_password
Pour Ruby on Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
manuellement on peut utiliser la méthode ci-dessous:
Nous pouvons modifier manuellement la migration comme:
-
app/db/migrate/xxxxxxxxx_migration_file.rb
Ouvrir -
Mise à jour
hased_password
àhashed_password
-
Exécutez la commande ci-dessous
$> rake db:migrate:down VERSION=xxxxxxxxx
Ensuite, il va supprimer votre migration:
$> rake db:migrate:up VERSION=xxxxxxxxx
Il ajoutera votre migration avec le changement mis à jour.
Générer le fichier de migration:
rails g migration FixName
# Crée db / migrate / xxxxxxxxxx.rb
Modifier la migration pour faire ta volonté.
class FixName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
Exécuter rails g migration ChangesNameInUsers
(ou tout ce que vous voulez le 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, puis exécutez rake db:migrate
dans la console
Consultez votre schema.db
afin de voir si le nom a réellement changé dans la base de données!
Hope this helps:)
$: rails g migration RenameHashedPasswordColumn
invoke active_record
create db/migrate/20160323054656_rename_hashed_password_column.rb
Ouvrez le fichier de migration et de modifier ce fichier comme ci-dessous (Ne tapez votre table_name
d'origine)
class RenameHashedPasswordColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
def change
rename_column :table_name, :old_column_name, :new_column_name
end
Générer un Ruby on Rails migration :
$:> rails g migration Fixcolumnname
Code d'insertion dans le fichier de migration (XXXXXfixcolumnname.rb) :
class Fixcolumnname < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
KISS. Il suffit de trois étapes simples. Les travaux suivants pour Rails 5.2 .
1. Créer une migration
-
rails g migration RenameNameToFullNameInStudents
-
rails g RenameOldFieldToNewFieldInTableName
- de cette façon, il est parfaitement clair pour les mainteneurs de la base de code plus tard. (Utiliser un pluriel pour le nom de la table).
2. Modifier la migration
# I prefer to explicitly write the
upand
downmethods.
# ./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 êtes hors de la course!
Ouvrez votre console Ruby on Rails et entrez:
ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
Vous avez deux façons de le faire:
-
Dans ce type, il exécute automatiquement le code inverse de celui-ci, quand rollback.
def change rename_column :table_name, :old_column_name, :new_column_name end
-
Pour ce type, il court vers le haut méthode lorsque
rake db:migrate
et exécute la méthode vers le bas lorsquerake 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
Je suis sur des rails 5.2, et en essayant de renommer une colonne sur un utilisateur DEVISE.
le bit rename_column
a fonctionné pour moi, mais le :table_name
singulier a lancé une « table utilisateur introuvable » erreur. Pluriel a travaillé pour moi.
rails g RenameAgentinUser
Modifiez ensuite le fichier de migration à ceci:
rename_column :users, :agent?, :agent
Où: Agent? est l'ancien nom de la colonne.
Il suffit de générer la migration commande en utilisant
rails g migration rename_hased_password
Après cela modifier la migration ligne suivante dans add méthode de changement
rename_column :table, :hased_password, :hashed_password
Cela devrait faire l'affaire.
Modifications de la migration Rails 5
par exemple:
modèle rails g Étudiant nom_étudiant : chaîne âge : entier
si tu veux changer nom d'étudiant colonne comme nom
Remarque : - si vous ne courez pas base de données rails: migrer
Vous pouvez effectuer les étapes suivantes
modèle rails d Étudiant nom_étudiant : chaîne âge : entier
Cela supprimera le fichier de migration généré. Vous pouvez maintenant corriger le nom de votre colonne.
modèle rails g Nom de l'étudiant : chaîne âge : entier
Si vous avez migré (rails db:migrate), options suivantes pour modifier le nom de la colonne
migration rails g RemoveStudentNameFromStudent student_name:string
migration rails g AddNameToStudent nom: chaîne
Mise à jour - Un proche cousin de create_table est change_table, utilisé pour changer les tables existantes. Il est utilisé de manière similaire à create_table, mais l'objet donné au bloc connaît plus de tours. 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
De cette façon est plus efficace si nous faisons avec d'autres méthodes de modification telles que: supprimer / ajouter index / supprimer index / ajouter la 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
#...