5

Auf Migration bekomme ich folgende Fehlermeldung:PG :: UndefinedTable: ERROR: Beziehung "..." existiert nicht

PG::UndefinedTable: ERROR: relation "actioncodes" does not exist 
: ALTER TABLE "organizations" ADD CONSTRAINT "fk_rails_4ecaa2493e" 
FOREIGN KEY ("actioncode_id") 
    REFERENCES "actioncodes" ("id") 

Ich habe folgende Migrationsdatei für Organisationen:

class CreateOrganizations < ActiveRecord::Migration 
    def change 
    create_table :organizations do |t| 
     t.string  :name,   null: false, limit: 40 
     t.references :actioncode, index: true, foreign_key: true 
     t.boolean :activated 
     t.datetime :activated_at 

     t.timestamps null: false 
    end 
    end 
end 

Und für Actioncodes habe ich die Migrationsdatei:

class CreateActioncodes < ActiveRecord::Migration 
    def change 
    create_table :actioncodes do |t| 
     t.string :code,   null: false, limit: 20 
     t.string :description,     limit: 255 

     t.timestamps null: false 
    end 
    end 
end 
class AddIndexToActioncodesCode < ActiveRecord::Migration 
    def change 
    add_index :actioncodes, :code, unique: true 
    end 
end 

Das Organisationsmodell-Datei enthält: belongs_to :actioncode .

Während die Actioncode-Modelldatei enthält: has_many :organizations.

Irgendeine Idee, was die Fehlermeldung verursachen könnte?

Wenn ich index: true, foreign_key: true aus der Migrationsdatei entferne, migriert es ohne Fehler. Und wenn ich diese Zeile mit der falschen Zeile t.references :actioncode_id, index: true, foreign_key: true ersetze, gibt es den Fehler unten, wo die letzte Zeile ("IDs") schlägt vor, dass Schienen irgendwie Problem mit dem Namen der Tabelle hat?

PG::UndefinedTable: ERROR: relation "actioncode_ids" does not exist 
: ALTER TABLE "organizations" ADD CONSTRAINT "fk_rails_604f95d1a1" 
FOREIGN KEY ("actioncode_id_id") 
    REFERENCES "actioncode_ids" ("id") 
+0

Der Tabellenname ist Actioncodes. Ich habe seine Migrationsdatei zum ursprünglichen Beitrag hinzugefügt – Nick

+1

Sieht so aus, als ob die 'CreateOrganizations'-Migration ausgeführt wird, bevor' CreateActioncodes' ausgeführt wird. - 'CreateActioncodes' soll zuerst ausgeführt werden, um sicherzustellen, dass die' actioncodes' Tabelle existiert. –

+0

Kannst du mir vielleicht raten, wie ich das ändern soll? Ich habe überprüft und der SQL-Code bestätigt tatsächlich, dass Organisationen vor Actioncodes erstellt werden. – Nick

Antwort

13

So das Problem geschieht, weil CreateOrganizations Migration ausgeführt wird, bevor CreateActioncodes ausgeführt wird.

CreateActioncodes ist zuerst auszuführen damit die action codes Tabelle vorhanden ist.

Die Reihenfolge, in der Migrationen ausgeführt werden, basiert auf dem Zeitstempel der Migration - wie im Namen der Datei angegeben. 20141014183645_create_users.rb wird vor 20141014205756_add_index_to_users_email.rb als Zeitstempel der zweiten ausgeführt - 20141014205756 ist nach der der ersten - 20141014183645.

Stellen Sie sicher, dass die Zeitstempel der Migration CreateOrganizations nach CreateActioncodes Migration sind.

Entweder Sie konnten den Zeitstempel in den Dateinamen manuell ändern. Oder löschen Sie diese Migrationsdateien und erstellen Sie sie in der richtigen Reihenfolge.

+0

Das hat funktioniert! Ich habe 'rails generiert Migration AddActioncodeToOrganizations actioncode: references' verwendet, um eine neue Migrationsdatei für die Referenz zu erstellen. Die Referenz aus der alten Migrationsdatei wurde entfernt (die ich für die anderen Variablen beibehalten habe). Die Antwort von @mu ist zwar zu kurz ist natürlich auch richtig, aber @Prakesh war nur etwas früher, also habe ich das als Lösung akzeptiert. – Nick

+0

Danke - etwas, das bei der Erstellung von db-Modellen leicht übersehen wird – Onichan

9

Die foreign_key: true in dieser Zeile:

t.references :actioncode, index: true, foreign_key: true 

sagt Rails einen Fremdschlüssel in der Datenbank zu erstellen. Ein foreign key:

constraint specifies that the values in a column (or a group of columns) must match the values appearing in some row of another table. We say this maintains the referential integrity between two related tables.

So ist es eine gewisse Logik in der Datenbank (wo er hingehört), die Sie nicht gewährleistet, ungültige Werte in Ihrer actioncode Spalte setzen können und dass Sie Einträge aus der actioncodes Tabelle nicht entfernen können, die woanders verwendet werden.

Um die Einschränkung zu erstellen, muss die referenzierte Tabelle (actioncodes) vorhanden sein, bevor Sie darauf verweisen. Sieht so aus, als ob Ihre Migrationen versuchen, organizations vor actioncodes zu erstellen, also müssen Sie nur die Migrationsdatei CreateOrganizations umbenennen, so dass ihr Timestamp-Präfix nach dem für CreateActioncodes kommt.Das Präfix ist nur ein Zeitstempel im Format JJJJMMTThhmmss. Ändern Sie daher den Zeitstempel CreateOrganizations in den Zeitstempel CreateActioncodes mit einer weiteren Sekunde.

3

Ich bekam auch diesen Fehler. Wenn Sie zum Ausführen von rspec eine Testdatenbank verwenden, stellen Sie sicher, dass Sie im Terminal [rake db:test:prepare] ausführen, bevor Sie rspec ausführen.