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?
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
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
.
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.
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.
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
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.
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 .
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.
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
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)
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
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
pour Ruby sur Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
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.
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
$: 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
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 :)
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
def change
rename_column :table_name, :old_column_name, :new_column_name
end
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, lors du roll-back.
def change rename_column :table_name, :old_column_name, :new_column_name end
-
à ce type, il exécute la méthode vers le haut quand
rake db:migrate
et exécute la méthode vers le bas quandrake 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 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.
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.
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
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
#...