web-dev-qa-db-fra.com

Ajout d'une colonne à une table existante dans une migration Rails

J'ai un modèle Utilisateurs qui nécessite 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, ai fait rake db:migrate et obtenu un NoMethodError. Puis j'ai ajouté la ligne

add_column :users, :email, :string

encore rake db:migrate, encore NoMethodError. Est-ce que je manque une étape ici?

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
307
John

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 lancera 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 tente 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).

531
Dylan Markow

Utilisez cette commande sur la console Rails

Rails generate migration add_fieldname_to_tablename fieldname:string

et

rake db:migrate

exécuter cette migration

107
vinodh

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 --- add_column à change:

_class AddEmailToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :email, :string
  end
end
_

Et puis exécutez _rake db:migrate_

38
Apoorv Agarwal

Vous pouvez aussi faire

rake db:rollback

si vous n'avez ajouté aucune donnée aux tables. Ensuite, éditez le fichier de migration en y ajoutant la colonne email, puis appelez

rake db:migrate

Cela fonctionnera si Rails 3.1 est installé dans votre système.

Une façon beaucoup plus simple de le faire est de changer, de laisser le changement dans le fichier de migration tel quel. utilisation

$rake db:migrate:redo

Cela annulera la dernière migration et la migrera à nouveau.

22
Ninz

Pour ajouter une colonne, je devais simplement suivre ces étapes:

  1. 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 attribuer à cette colonne.

    Note: Les noms de table dans Rails sont toujours au pluriel (pour correspondre aux conventions de base de données). Exemple utilisant l'une des étapes mentionnées précédemment -

    Rails generate migration addEmailToUsers

  2. rake db:migrate

Ou

  1. Vous pouvez modifier le schéma depuis db/schema.rb, ajoutez les colonnes souhaitées dans la requête SQL.
  2. Exécutez cette commande: rake db:schema:load

    Avertissement/Note

    N'oubliez pas que l'exécution de rake db:schema:load efface automatiquement toutes les données de vos tableaux.

18
Pratik Naik

Lorsque j'ai fait cela, plutôt que de manipuler la migration d'origine, j'en crée une nouvelle avec uniquement la colonne add dans la section up et une colonne drop dans la section down.

Vous pouvez modifier l'original et l'exécuter à nouveau si vous effectuez une migration vers le bas, mais dans ce cas, je pense que cela a créé une migration qui ne fonctionnera pas correctement.

Dans votre version actuelle, vous ajoutez la colonne, puis vous créez la table.

Si vous modifiez l'ordre, cela pourrait fonctionner. Ou, lorsque vous modifiez une migration existante, ajoutez-la simplement à la table de création au lieu de créer une colonne d'ajout séparée.

3
Don Roby

Vous pouvez également forcer la table des colonnes dans 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
1
Aravin

Vous pouvez annuler la dernière migration en

rake db:rollback STEP=1

ou annuler cette spécifique migration par

rake db:migrate:down VERSION=<YYYYMMDDHHMMSS>

et éditez le fichier, puis exécutez à nouveau rake db:mirgate.

0
fangxing

Vous pouvez également le faire .. Rails g Migration add_column_to_users email: string

alors rake db: migrate ajoute également: attribut email dans votre contrôleur utilisateur;

pour plus de détails, consultez http://guides.rubyonrails.org/active_record_migrations.html

0
aaquib