web-dev-qa-db-fra.com

Ruby on Rails: ajout de colonnes à la base de données existante

Je reçois une erreur:

SQLite3::SQLException: no such column: ideas.list_id: 
SELECT "ideas".* FROM "ideas"  
WHERE "ideas"."list_id" = 2

Mais j'ai ajouté

t.integer :list_id

dans mon fichier de migration db:

class CreateIdeas < ActiveRecord::Migration
  def change
    create_table :ideas do |t|
      t.string :name
      t.text :description
      t.string :picture

      t.timestamps
    end
    add_foreign_key :ideas, :lists
  end
end

ce qui m'a donné ceci:

class CreateIdeas < ActiveRecord::Migration
  def change
    create_table :ideas do |t|
      t.string :name
      t.text :description
      t.string :picture
      t.integer :list_id
      t.timestamps
    end
    add_foreign_key :ideas, :lists
  end
end

puis j'ai tapé

rake db:migrate

Une idée pourquoi j'obtiendrais une erreur disant qu'il n'y a pas de colonne? Je suis encore nouveau sur RoRs. Dois-je ajouter une colonne d'une autre manière?

Merci

19
hellomello

Comme l'a suggéré Speransky, vous ne devez jamais modifier d'anciens fichiers de migration. Vous devez plutôt créer une nouvelle migration qui ajoute la colonne souhaitée. Par exemple, dans ce cas, vous devez exécuter la commande suivante dans votre application pour créer la nouvelle migration:

Rails generate migration AddListIdColumnToIdeas list_id:integer

Et Rails générerait automatiquement le fichier de migration et la seule chose qu'il reste à faire est d'exécuter rake db:migrate.

Si vous insistez pour modifier l'ancien fichier de migration, vous pouvez ajouter la colonne comme vous l'avez fait et exécuter ce qui suit:

rake db:drop
rake db:create
rake db:migrate

Ce qui détruira votre base de données actuelle, en créera une nouvelle et exécutera toutes les migrations (qui incluront votre nouvelle colonne).

53
amb110395

Si vous souhaitez ajouter une nouvelle colonne à une base de données existante, vous devez utiliser Rails generate migration. Vous pouvez donc essayer Rails generate migration add_list_id_to_ideas list_id:integer puis utilisez rake db:migrate pour valider cette modification.

3
Edgar Wang

Vous ne devez pas ajouter de nouvelles lignes aux anciennes migrations. La migration est une étape de construction de la base de données. Et le nombre de la dernière migration exécutée est stocké dans schema, et il ne sera pas exécuté ou refait si vous utilisez utilisera rake db:migrate. Si vous exécutez la migration en créant la table auparavant, vous devez créer une nouvelle migration où vous pouvez utiliser add_column méthode.

2
Danil Speransky

Vous pouvez également le faire ..

Rails g migration add_column_to_users list_id:string

puis rake db:migrate

aussi add :list_id attribut dans votre contrôleur utilisateur;

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

1
aaquib

Rails 4.0 moyen facile d'ajouter une ou plusieurs colonnes https://Gist.github.com/pyk/8569812

1
Nikhil Thombare

le nom du fichier de migration a le datetime encodé dans son nom donc Rails exécutez celui-ci et ne le relancez pas sauf si vous faites une restauration

et voici la magie de la migration pour vous construire db avec de petites étapes donc pas besoin de mettre à jour une migration après avoir exécuté rake db: migrer, vous devriez faire une nouvelle migration pour faire le changement que vous voulez sur votre schéma db

et n'oubliez pas de

supprimez la ligne ajoutée de l'ancien fichier de migration car cela pourrait générer des erreurs si vous décidiez d'annuler cette migration

1
abo-elleef

Si vous avez déjà des fichiers dans votre dossier de migration, vous pouvez simplement ajouter la colonne de votre choix (tapez simplement le code), supprimez development.sqlite ou tout ce qui représente votre fichier db et exécutez rake db: migrate. Il créera ensuite un nouveau fichier sqlite avec une nouvelle colonne dans le tableau, et vous pouvez le vérifier dans schema.rb

Donc, fondamentalement, tout ce que vous avez fait semble bon, sauf que vous n'avez pas supprimé votre fichier de base de données. Cela me semble le plus simple, même si vous perdrez tous les fichiers de votre base de données. Si vous testez et développez simplement l'application Rails, cela fonctionne. Quelqu'un peut-il commenter s'il y a quelque chose qui ne va pas dans cette approche, en plus de ce que j'ai écrit?

Edit: J'ai trouvé une réponse à ce sujet ici (Modifier les migrations existantes Rails Migrations est une bonne idée?

0
Marko