5

Na migracji pojawia się następujący komunikat o błędzie:PG :: UndefinedTable: ERROR: relacja "..." nie istnieje

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

Mam następujący plik migracji dla organizacji:

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 

I Actioncodes mam plik migracji:

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 

plik modelu organizacja obejmuje: belongs_to :actioncode .

Podczas gdy plik modelu actioncodes zawiera: has_many :organizations.

Jakieś pojęcie, co może być przyczyną komunikatu o błędzie?

Po usunięciu index: true, foreign_key: true z pliku migracji migracja przebiega bezbłędnie. A kiedy zamieniam tę linię na nieprawidłową linię t.references :actioncode_id, index: true, foreign_key: true, podaje ona błąd poniżej, gdzie ostatnia linia ("ids") sugeruje, że Rails jakoś wydaje się mieć problem z nazwą tabeli?

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

Nazwa tabeli to kody akcji. Dodałem plik migracji do oryginalnego posta. – Nick

+1

Wygląda na to, że migracja 'CreateOrganizations' jest uruchamiana przed wykonaniem' CreateActioncodes'. - Najpierw należy uruchomić "CreateActioncodes", upewniając się, że istnieje tabela "actioncodes". –

+0

Czy możesz poradzić, jak powinienem to zmienić? Sprawdziłem i kod SQL rzeczywiście potwierdza Organizacje są tworzone przed kodem Action. – Nick

Odpowiedz

13

Więc sprawa się dzieje, ponieważ CreateOrganizations migracja jest prowadzony przed CreateActioncodes jest wykonywany. Najpierw należy uruchomić

CreateActioncodes, zapewniając, że istnieje tabela action codes.

Kolejność wykonywania migracji jest oparta na sygnaturze czasowej migracji - zgodnie z nazwą pliku. 20141014183645_create_users.rb będzie działać przed 20141014205756_add_index_to_users_email.rb jako znacznik czasu drugiego - 20141014205756 jest po tym terminie pierwszego - .

Upewnij się, że znaczniki czasu migracji CreateOrganizations są późniejsze niż migracja CreateActioncodes.

Można ręcznie zmienić znacznik czasu w nazwach plików. Lub usuń te pliki migracji i utwórz je we właściwej kolejności.

+0

To zadziałało! Użyłem 'rails generate migration AddActioncodeToOrganizations actioncode: references', aby utworzyć nowy plik migracji dla odniesienia. Usunięto odniesienie ze starego pliku migracji (który zachowałem dla pozostałych zmiennych). Odpowiedź od @mu jest zbyt krótka, oczywiście jest również właściwa, ale @Prakesh był nieco wcześniejszy, więc zaakceptowałem to jako rozwiązanie. – Nick

+0

Dzięki - coś łatwo przeoczyć podczas generowania modeli db – Onichan

9

foreign_key: true w tej linii:

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

mówi Rails utworzyć klucz obcy wewnątrz bazy danych. 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.

Więc to jest jakaś logika w bazie danych (gdzie należy), która gwarantuje, że nie można umieścić nieprawidłowe wartości w kolumnie actioncode i że nie można usunąć wpisy z tabeli actioncodes które są używane gdzie indziej.

Aby utworzyć wiązanie, odwoływana tabela (actioncodes) musi istnieć przed jej odwołaniem. Wygląda na to, że Twoje migracje próbują utworzyć organizations przed actioncodes, więc wszystko, co musisz zrobić, to zmienić nazwę pliku migracyjnego CreateOrganizations, tak aby jego prefiks znacznika czasu pojawił się po prefiksie dla CreateActioncodes.Prefiks jest tylko znacznikiem czasu w formacie RRRRMMDDggmmss, dlatego zmień znacznik czasu CreateOrganizations na znacznik czasu CreateActioncodes za pomocą jeszcze jednej sekundy.

3

Otrzymałem również ten błąd. Jeśli używasz testowej bazy danych do uruchomienia rspec, upewnij się, że uruchom terminal [rake db:test:prepare] w terminalu przed uruchomieniem rspec.

Powiązane problemy