Ich habe ein Modell namens "Benutzer" erstellt und eine neue Migration erstellt, um der Benutzertabelle einige Spalten hinzuzufügen. Wenn ich nun rake db: migrate starte, erhalte ich die Fehlermeldung unter b/c, es versucht, die Benutzertabelle erneut zu erstellen
$ 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`.....
Warum versucht es die Tabelle erneut zu erstellen?
Hier ist der Befehl, mit dem ich die neue Migration erstellt habe
$ 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
Die neue Migration sieht folgendermaßen aus:
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
EDIT
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 verfolgt die Migrationen in der Tabelle "schema_migrations" Ihrer Datenbank. Wenn es keinen Eintrag für "20120511224920" gibt, also die Devise-Migration, wird es erneut versucht, es erneut auszuführen, was scheinbar bereits vorhanden ist.
In diesem Fall können Sie dies manuell zur Tabelle hinzufügen.
Der Fehler besagt, dass versucht wird, die ursprüngliche DeviseCreateUsers-Migration erneut auszuführen. Dies ist jedoch nicht möglich, da die Benutzertabelle bereits vorhanden ist.
Um dies zu beheben, können Sie die Down-Migration für DeviseCreateUsers
und dann wie üblich Migrationen ausführen. Das kannst du mit:
rake db:migrate:down VERSION=20121031XXXXXXXX
rake db:migrate
Dabei ist 20121031XXXXXXXX
der Datumsstempel des Migrationsnamens. Mit anderen Worten, Sie haben eine Migration mit dem Namen 20120410214815_devise_create_users.rb
und kopieren den Datumsstempel aus dem Dateinamen und fügen ihn in den Befehl ein. Hier ist der Rails Guide zu Migrationen als Referenz .
Edit: Dies ist in den Kommentaren vermerkt, aber nur ein Wort der Warnung. Wenn Sie die Abwärtsmigration für eine Tabelle ausführen, gehen alle Einträge der Tabelle verloren. Ich gehe davon aus, dass Sie im Entwicklungsmodus laufen, daher sollte dies kein Problem sein. Wenn Sie in der Produktion sind, müssen Sie zusätzliche Schritte unternehmen, um die Tabellendaten zu sichern und anschließend erneut zu laden. Andernfalls haben Sie einen schlechten Tag (oder möglicherweise eine Woche).
Können Sie versuchen, eine neue Datenbank zu erstellen und diese dann erneut zu migrieren:
rake db:drop:all
rake db:create:all
rake db:migrate
Also aus dem, was ich daraus gezogen habe:
Ich hoffe das:
HINWEIS: Wenn dies nicht der Fall ist, erfahren Sie, warum Sie dies tun müssen.
Stelle den Code wieder her, bevor du Devise erstellt hast
Hoffentlich können Sie einfach eine neue Sandbox eines Punktes erstellen, bevor Sie Devise generieren. Wenn nicht, kopieren Sie Ihr Projektverzeichnis und machen Sie es von Hand. Die einzige andere Option ist die manuelle Bearbeitung aller von Devise generierten Dateien.
Wiederhole deine Devise Generation
Stellen Sie sicher, dass das Modell nicht existiert! Wenn Sie nicht in das Problem geraten, das Sie gerade haben.
Aktuelle Benutzer von einem Modell zum anderen migrieren
Wenn Sie ein Skript generieren können, um die Authentifizierungsinformationen vollständig von Ihrem alten Benutzermodell in das neue zu verschieben, ist dies für Sie gut. Wenn Sie für Ihre aktuelle Authentifizierung einen anderen Hash-Algorithmus als Devise verwenden, müssen Sie entweder alle ihre Passwörter ungültig machen und die Benutzer müssen ein neues Passwort mit einem Bestätigungscode in ihrer E-Mail OR erstellen, den Sie migrieren könnten Benutzer beim Anmelden. Die erste Methode ist sauber, vollständig und unhöflich. Die zweite Methode ist hässlich, unvollständig und stumm. Wählen Sie Ihre Methode, wie Sie möchten.
Bearbeiten: Möglicherweise finden Sie eine Möglichkeit, Devise an Ihre Algorithmen anzupassen. Das wäre wahrscheinlich noch besser, aber ein bisschen mehr Arbeit und ziemlich spröde.
Eine andere Sache ist, dass Ihr Authentifizierungsmodell nicht mit Kontodaten überladen werden sollte. Sie sollten über ein Modell verfügen, das nur die Authentifizierung ausführt, bei dem has_a ein Kontendatenmodell gespeichert ist, in dem gespeichert ist, was Sie möglicherweise über Konten nachverfolgen möchten.
verwenden Sie auf und ab Methoden. Dies ist hilfreich für das Rollback und das Ausführen bestimmter Migrationsdateien.
Bitte folgen Sie der Syntax ..
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.
Wie rake db: migrate: down VERSION = Versionsnummer #Versionsnummer gibt an, welche Version Sie migrieren möchten.
Suchen Sie nach Umgebungsvariablen, die möglicherweise einen unerwarteten Wert für die Version Ihrer Migration liefern. Ich fand eine alte Frage bei Stack Overflow (und vergib mir, wenn es nicht mehr aktuell ist), wo db:migrate
die Tabelle zerstörte, anstatt eine bestehende neue Migration anzuwenden.
Sie stellten schließlich fest, dass eine Umgebungsvariable dazu führte, dass db:migrate
mit einem Versionsparameter "0" ausgeführt wurde, der funktional äquivalent zu rake db:migrate:down
ist.
Ist es möglich, dass Ihre Situation dadurch verursacht wurde, dass die Version unerwartet geändert wurde, um die vorherige Migration DeviseCreateUsers
aufzunehmen oder abzugleichen?
Ich nehme an, Sie haben irgendwann Rails generate devise user
ausgeführt, wodurch DeviseCreateUsers
generiert wurde. Wenn Sie bereits ein Benutzermodell und eine Benutzertabelle erstellt haben, können Sie die generierte Migrationsdatei aus db/migrate löschen.
Und wenn Sie einige schmutzige Migrationen manuell durchführen müssen:
class A < ActiveRecord::Migration
def up
add_column :images, :name
end
end
A.new.migrate(:up)
versuch's einfach
in der ersten Datei
create_table(:users), :force => true do |t|
dadurch wird jede andere Tabelle überschrieben
Wie Sie sagten, haben Sie diesen Befehl zum Erstellen einer neuen Migration verwendet
$ Rails erzeugen Migration AddDetailsToUsers home_phone: decimal cell_phone: decimal work_phone: decimal geburtstag: date home_address: text work_address: text position: string firma: string
Ich bin nicht sicher, ob es sich nur um einen Tippfehler handelt, es sollte jedoch "AddDetailsToUser" und nicht "Users" sein. Einfach nochmal nachschauen und wir können Ihnen helfen. Dies ist für das erzeugte Modell. Wenn Sie Benutzer erwähnen, wird in db nach Benutzern gesucht.
Ruby on Rails folgt der linguistischen Konvention.Tabellenname ist Plural, aber Modellname ist Singular. In dem von Ihnen verwendeten Befehl müssen Sie Modellname verwenden.
Wenn Sie tabellenname verwenden möchten, verwenden Sie diese Option
Rails g Migration add_details_to_users home_phone: dezimal ...... etc