Ajout d'une colonne à une table existante dans une migration Rails
J'ai un modèle Users qui a besoin d'une colonne :email
(j'ai oublié d'ajouter cette colonne lors de l'échafaudage initial).
J'ai ouvert le fichier de migration et ajouté t.string :email
, fait rake db:migrate
, et a obtenu un NoMethodError
. Puis j'ai ajouté la ligne
add_column :users, :email, :string
Encore rake db:migrate
, encore NoMethodError
. Ai-je raté une étape?
Edit: voici le fichier de migration.
class CreateUsers < ActiveRecord::Migration
def self.up
add_column :users, :email, :string
create_table :users do |t|
t.string :username
t.string :email
t.string :crypted_password
t.string :password_salt
t.string :persistence_token
t.timestamps
end
end
def self.down
drop_table :users
end
end
9 réponses
Si vous avez déjà exécuté votre migration d'origine (avant de la modifier), vous devez générer une nouvelle migration (rails generate migration add_email_to_users email:string
fera l'affaire). Ensuite, faites un rake db:migrate
et il exécutera la nouvelle migration.
Si vous n'avez pas encore exécuté la migration d'origine, vous pouvez simplement la modifier, comme vous essayez de le faire. Votre code de migration est presque parfait: il vous suffit de supprimer complètement la ligne add_column
(ce code essaie d'ajouter une colonne à une table, avant que la table ait été créée, et votre table le code de création a déjà été mis à jour pour inclure un t.string :email
de toute façon).
Utilisez cette commande sur la console rails
rails generate migration add_fieldname_to_tablename fieldname:string
Et
rake db:migrate
pour exécuter cette migration
Vous pouvez également faire
rake db:rollback
Si vous n'avez pas ajouté de données aux tables.Modifiez ensuite le fichier de migration en y ajoutant la colonne E-Mail, puis appelez
rake db:migrate
Cela fonctionnera si vous avez rails 3.1 partir installé dans votre système.
Une façon beaucoup plus simple de le faire est de changer que le changement dans le fichier de migration soit tel qu'il est. utiliser
$rake db:migrate:redo
.
Cela annulera la dernière migration et la migrera à nouveau.
Parfois rails generate migration add_email_to_users email:string
produit une migration comme celle-ci
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
end
end
, Dans ce cas, vous devez manuellement une ligne supplémentaire à change
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :email, :string
end
end
, puis exécutez rake db:migrate
Pour ajouter une colonne, j'ai juste dû suivre ces étapes:
-
rails generate migration add_fieldname_to_tablename fieldname:string
Alternative
rails generate migration addFieldnameToTablename
Une fois la migration générée, Modifiez - la et définissez tous les attributs que vous souhaitez ajouter à cette colonne.
Note: les noms de Table dans Rails sont toujours au pluriel (pour correspondre aux conventions DB). Exemple à l'aide de l'une des étapes mentionnées précédemment-
rails generate migration addEmailToUsers
rake db:migrate
Ou
- , Vous pouvez modifier le schéma à partir de
db/schema.rb
, Ajouter les colonnes que vous voulez dans la requête SQL. -
Exécutez cette commande:
rake db:schema:load
Avertissement/Remarque
Gardez à l'esprit que l'exécution de
rake db:schema:load
efface automatiquement toutes les données de vos tables.
Lorsque je l'ai fait, plutôt que de tripoter la migration d'origine, j'en crée une nouvelle avec juste la colonne add dans la section up et une colonne drop dans la section down.
Vous pouvez changer l'original et le réexécuter si vous migrez entre, mais dans ce cas, je pense que cela a fait une migration qui ne fonctionnera pas correctement.
Comme actuellement affiché, vous ajoutez la colonne, puis créez la table.
Si vous modifiez l'ordre, cela pourrait fonctionner. Ou, comme vous l'êtes de la modification d'une migration existante, ajoutez-la simplement à la table create au lieu de faire une colonne add séparée.
Vous pouvez également forcer les colonnes de table dans la table en utilisant force: true
, si votre table existe déjà.
Exemple:
ActiveRecord::Schema.define(version: 20080906171750) do
create_table "authors", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Vous pouvez annuler la dernière migration par
rake db:rollback STEP=1
Ou annuler cette migrationspécifique par
rake db:migrate:down VERSION=<YYYYMMDDHHMMSS>
Et éditez le fichier, puis exécutez à nouveau rake db:mirgate
.
Vous pouvez également le faire .. rails g de migration add_column_to_users e-mail:string
Puis rake db: migrer ajoutez également :attribut email dans votre contrôleur utilisateur;
Pour plus de détails consultez http://guides.rubyonrails.org/active_record_migrations.html