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?
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?
Réponses:
rename_column :table, :old_column, :new_column
Vous souhaiterez probablement créer une migration distincte pour ce faire. (Renommez FixColumnName
comme vous voulez.):
script/generate migration FixColumnName
# creates db/migrate/xxxxxxxxxx_fix_column_name.rb
Modifiez ensuite 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
Pour l'utilisation de Rails 3.1:
Alors que les méthodes up
et down
s'appliquent toujours, Rails 3.1 reçoit une change
méthode qui "sait comment migrer votre base de données et l'inverser lorsque la migration est annulée sans avoir besoin d'écrire une méthode distincte".
Voir « Migrations d'enregistrements actifs » pour plus d'informations.
rails g migration FixColumnName
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
S'il vous arrive d'avoir 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 pouvez utiliser change_table
pour garder les choses 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
Ensuite, db:migrate
comme d'habitude ou comme vous allez pour vos affaires.
Pour Rails 4:
Lors de la création d'un Migration
pour renommer une colonne, Rails 4 génère une change
méthode au lieu de up
et down
comme mentionné dans la section ci-dessus. La change
méthode générée est:
$ > rails g migration ChangeColumnName
qui va créer un fichier de migration similaire à:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
self.up
je ne dirais pas self.down
"devrait toujours être opposé". En dépend du contexte de votre migration. Mettre simplement le «contraire» pourrait ne pas être la «bonne» migration vers le bas.
def self.up
et def self.down
avec def change
et il saura comment revenir en arrière.
change
méthode n'est pas une preuve complète, ont donc tendance à utiliser up
et les down
méthodes pour les migrations complexes.
À mon avis, dans ce cas, il est préférable d'utiliser rake db:rollback
, puis de modifier votre migration et d'exécuter à nouveau rake db:migrate
.
Cependant, si vous avez des données dans la colonne que vous ne voulez pas perdre, utilisez-les rename_column
.
Si la colonne est déjà remplie de données et est en production, je recommanderais une approche étape par étape, afin d'éviter les temps d'arrêt en production en attendant les migrations.
Je créerais d'abord une migration de base de données pour ajouter des colonnes avec le ou les nouveaux noms 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
Ensuite, j'engagerais juste ce changement et le mettrais en production.
git commit -m 'adding columns with correct name'
Ensuite, une fois le commit mis en production, je courais.
Production $ bundle exec rake db:migrate
Ensuite, je mettrais à jour toutes les vues / contrôleurs qui faisaient référence à l'ancien nom de colonne au nouveau nom de colonne. Parcourez ma suite de tests et validez uniquement ces modifications. (Après vous être assuré qu'il fonctionnait localement et avoir réussi 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 tout type 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
Poussez ensuite cette dernière migration vers la production et exécutez-la 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 plutôt que d'avoir des problèmes avec ma migration de production.
execute "Update table_name set correct_name_column_one = old_name_column_one"
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.
rename_column
.
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, écrivez rename_column
comme ci-dessous:
class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Certaines versions de Ruby on Rails prennent en charge la méthode de montée / descente vers la migration et si vous avez une méthode de montée / descente 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 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 .
Si votre code n'est pas partagé avec un autre, la meilleure option est de le faire, rake db:rollback
puis de modifier le nom de votre colonne dans la 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.
rake db:rollback
est une excellente suggestion. Mais comme vous l'avez dit, seulement si la migration n'a pas encore été repoussée.
Comme alternative, si vous n'êtes pas marié avec l'idée de migrations, il existe un joyau convaincant pour ActiveRecord qui gérera automatiquement les changements de nom 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 Model.auto_upgrade! Au bas de votre model.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 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 aucun problème)
Si vous devez changer de nom de colonne, vous devrez créer un espace réservé pour éviter une 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
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 relancez la migration vers le haut en:
rake db:migrate
Pour Ruby on Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
Manuellement, nous pouvons utiliser la méthode ci-dessous:
Nous pouvons modifier la migration manuellement comme:
Ouvert app/db/migrate/xxxxxxxxx_migration_file.rb
Mettre hased_password
à jour vershashed_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 la modification mise à jour.
Courez rails g migration ChangesNameInUsers
(ou ce que vous voudriez lui donner)
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 exécutez-le 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 :)
Faisons un baiser . Il suffit de trois étapes simples. Les travaux suivants pour Rails 5.2 .
rails g migration RenameNameToFullNameInStudents
rails g RenameOldFieldToNewFieldInTableName
- de cette façon, il est parfaitement clair pour les responsables de la base de code plus tard. (utilisez un pluriel pour le nom de la table).
# I prefer to explicitly write the
de haut en and
basmethods.
# ./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
rake db:migrate
Et c'est parti pour les courses!
$: rails g migration RenameHashedPasswordColumn
invoke active_record
create db/migrate/20160323054656_rename_hashed_password_column.rb
Ouvrez ce fichier de migration et modifiez ce fichier comme ci-dessous (entrez votre original table_name
)
class RenameHashedPasswordColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
Ouvrez votre console Ruby on Rails et entrez:
ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
Vous avez deux façons de procéder:
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
Pour ce type, il exécute la méthode up quand 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
Je suis sur les rails 5.2 et j'essaie de renommer une colonne sur un utilisateur de devise.
le rename_column
bit a fonctionné pour moi, mais le singulier a :table_name
lancé une erreur "Table utilisateur non trouvée". Le pluriel a fonctionné pour moi.
rails g RenameAgentinUser
Ensuite, changez le fichier de migration en ceci:
rename_column :users, :agent?, :agent
Où: agent? est l'ancien nom de la colonne.
Update - 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 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 le faisons avec d'autres méthodes de modification 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
#...
Générez simplement la migration à l'aide de la commande
rails g migration rename_hased_password
Après cela, modifiez la migration, ajoutez la ligne suivante dans la méthode de changement
rename_column :table, :hased_password, :hashed_password
Cela devrait faire l'affaire.
Modifications de la migration de Rails 5
par exemple:
rails g model Student nom_étudiant: string age: integer
si vous voulez changer la colonne nom_étudiant en nom
Remarque: - si vous n'exécutez pas rails db: migrez
Vous pouvez faire les étapes suivantes
rails modèle d Etudiant Student_name: string age: integer
Cela supprimera le fichier de migration généré, vous pouvez maintenant corriger le nom de votre colonne
rails g modèle Nom de l'élève: âge de la chaîne: entier
Si vous avez migré (rails db: migrate), les options suivantes pour modifier le nom de la colonne
migration des rails g RemoveStudentNameFromStudent nom_étudiant: chaîne
rails g migration AddNameToStudent nom: chaîne
rails g migration RemoveStudentNameFromStudentS student_name:string
(les élèves sont pluriels)?