J'ai créé un modèle appelé "utilisateurs" et j'ai créé une nouvelle migration pour ajouter des colonnes à la table des utilisateurs. Maintenant, quand je lance rake db: migrate, j'obtiens l'erreur ci-dessous, car il essaie de créer à nouveau la table users
$ rake db:migrate
== DeviseCreateUsers: migrating ==============================================
-- create_table(:users)
rake aborted!
An error has occurred, all later migrations canceled:
Mysql::Error: Table 'users' already exists: CREATE TABLE `users`.....
Pourquoi essaie-t-il de créer à nouveau la table?
Voici la commande que j'ai utilisée pour créer la nouvelle migration
$ Rails generate migration AddDetailsToUsers home_phone:decimal cell_phone:decimal work_phone:decimal birthday:date home_address:text work_address:text position:string company:string
La nouvelle migration ressemble à ceci:
class AddDetailsToUsers < ActiveRecord::Migration
def change
add_column :users, :home_phone, :decimal
add_column :users, :cell_phone, :decimal
add_column :users, :work_phone, :decimal
add_column :users, :birthday, :date
add_column :users, :home_address, :text
add_column :users, :work_address, :text
add_column :users, :position, :string
add_column :users, :company, :string
end
end
MODIFIER
20120511224920_devise_create_users
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :username, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Encryptable
# t.string :password_salt
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
## Token authenticatable
# t.string :authentication_token
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
# add_index :users, :confirmation_token, :unique => true
# add_index :users, :unlock_token, :unique => true
# add_index :users, :authentication_token, :unique => true
end
end
20120619023856_add_name_to_users
class AddNameToUsers < ActiveRecord::Migration
def change
add_column :users, :first_name, :string
add_column :users, :last_name, :string
end
end
20121031174720_add_details_to_users.rb
class AddDetailsToUsers < ActiveRecord::Migration
def change
add_column :users, :home_phone, :decimal
add_column :users, :cell_phone, :decimal
add_column :users, :work_phone, :decimal
add_column :users, :birthday, :date
add_column :users, :home_address, :text
add_column :users, :work_address, :text
add_column :users, :position, :string
add_column :users, :company, :string
end
end
Rails garde la trace des migrations dans la table "schema_migrations" de votre base de données. À moins d'une entrée pour "20120511224920", qui correspond à la migration de Devise, il tentera de l'exécuter à nouveau, ce qui semble déjà exister.
Vous pouvez l'ajouter manuellement à la table si c'est le cas.
L'erreur indique qu'il tente d'exécuter à nouveau la migration DeviseCreateUsers d'origine et ne peut pas le faire car la table users existe déjà.
Pour résoudre ce problème, vous pouvez exécuter la migration vers le bas pour DeviseCreateUsers
, puis exécuter les migrations normalement. Vous pouvez le faire avec:
rake db:migrate:down VERSION=20121031XXXXXXXX
rake db:migrate
Où 20121031XXXXXXXX
correspond à l'horodatage du nom de la migration. En d'autres termes, vous aurez une migration nommée 20120410214815_devise_create_users.rb
et vous copiez l'horodatage à partir du nom de fichier et le collez dans la commande. Voici le Guide Rails sur les migrations .
Edit: Ceci est noté dans les commentaires, mais juste un mot d'avertissement. L'exécution de la migration vers le bas pour une table perdra toutes les entrées de cette table. Je suppose que vous travaillez en mode développement, donc cela ne devrait pas poser de problème. Si vous êtes en production, vous devrez prendre des mesures supplémentaires pour sauvegarder les données de la table et les recharger après, sinon vous passerez une mauvaise journée (ou peut-être une semaine).
Pouvez-vous essayer de créer une nouvelle base de données puis de la migrer à nouveau:
rake db:drop:all
rake db:create:all
rake db:migrate
Donc, d'après ce que j'en ai tiré:
J'espère que:
NOTE: Sinon, vous êtes sur le point de savoir pourquoi vous devez le faire.
Revenez à votre code avant de générer Devise
Espérons que vous pouvez simplement créer un nouveau bac à sable d'un point juste avant de générer Devise. Sinon, copiez votre répertoire de projet et faites-le à la main. La seule autre option est de modifier manuellement tous les fichiers générés par Devise.
Relancez votre génération Devise
Assurez-vous que ce modèle n'existe pas! Si vous n'entrez pas dans le problème que vous rencontrez actuellement.
Migrer les utilisateurs actuels d'un modèle à l'autre
Si vous pouvez générer un script pour déplacer complètement les informations d'authentification de votre ancien modèle d'utilisateur vers le nouveau, c'est bon pour vous. Si vous utilisez un algorithme de hachage différent de Devise pour votre authentification actuelle, vous allez alors invalider tous leurs mots de passe et demander à vos utilisateurs de créer un nouveau mot de passe en utilisant un code de confirmation dans leur courrier électronique OR que vous pouvez migrer. utilisateurs lorsqu’ils se connectent. La première méthode est propre, complète et grossière. La seconde méthode est laide, incomplète et silencieuse. Choisissez votre méthode comme bon vous semble.
Edit: Vous pourriez probablement trouver un moyen de personnaliser Devise pour utiliser votre algorithme à la place. Ce serait probablement encore mieux, mais un peu plus de travail et assez fragile.
Une autre chose est que votre modèle d'authentification ne doit pas être surchargé de données de compte. Vous devriez avoir un modèle qui gère uniquement l’authentification, qui a_un modèle de données de compte qui stocke tout ce que vous voudriez suivre sur les comptes.
utiliser des méthodes de haut en bas. Cela sera utile pour la restauration et l'exécution d'un fichier de migration spécifique.
S'il vous plaît suivez la syntaxe ..
class AddDetailsToUsers < ActiveRecord::Migration
def self.up
add_column :users, :home_phone, :decimal
add_column :users, :cell_phone, :decimal
add_column :users, :work_phone, :decimal
add_column :users, :birthday, :date
add_column :users, :home_address, :text
add_column :users, :work_address, :text
add_column :users, :position, :string
add_column :users, :company, :string
end
def self.down
remove_column :users, :home_phone
remove_column :users, :cell_phone
remove_column :users, :work_phone
remove_column :users, :birthday
remove_column :users, :home_address
remove_column :users, :work_address
remove_column :users, :position
remove_column :users, :company
end
end
In this case please try to migrate using version number.
Comme rake db: migrate: down VERSION = numéro de version # numéro de version est la version que vous souhaitez migrer.
Recherchez certaines variables d'environnement susceptibles de fournir une valeur inattendue pour la version de votre migration. J'ai trouvé une vieille question sur Stack Overflow (et pardonnez-moi si c'est obsolète) où db:migrate
détruisait la table, au lieu d'appliquer une nouvelle migration existante.
Ils ont finalement découvert qu'une variable d'environnement provoquait l'exécution de db:migrate
avec un paramètre de version de "0" fonctionnellement équivalent à rake db:migrate:down
.
Est-il possible que votre situation soit due à une modification inattendue de la version afin d'inclure ou de faire correspondre la migration précédente DeviseCreateUsers
?
Je suppose que vous avez parfois utilisé Rails generate devise user
qui a généré DeviseCreateUsers
. Si vous avez déjà créé un modèle d'utilisateur et une table d'utilisateurs, vous pouvez supprimer le fichier de migration généré de db/migrate.
Et si vous avez besoin de faire des migrations sales manuellement:
class A < ActiveRecord::Migration
def up
add_column :images, :name
end
end
A.new.migrate(:up)
juste essayer
dans le premier fichier
create_table(:users), :force => true do |t|
cela remplacera toute autre table
Selon ce que vous avez dit, vous avez utilisé cette commande pour créer une nouvelle migration.
$ Rails génère la migration AddDetailsToUsers home_phone: decimal cell_phone: decimal work_phone: decimal anniversaire: date home_address: text work_address: position text: string company: string
Je ne suis pas sûr que ce soit juste une faute de frappe, mais il devrait s'agir de "AddDetailsToUser" et non de "Utilisateurs". Il suffit de vérifier à nouveau et nous serons en mesure de vous aider. Ceci est pour le modèle généré. Lorsque vous mentionnez User, la base de données recherche des utilisateurs.
Ruby on Rails suit linguistic convention.nom_table est pluriel mais nom_module est singulier. Vous devez utiliser model_name dans la commande que vous avez utilisée.
Si vous voulez utiliser nom_table, utilisez ceci
Rails g migration add_details_to_users home_phone: décimal ...... etc