5

在遷移我收到以下錯誤信息:PG :: UndefinedTable:ERROR:關係 「......」 不存在

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

我對組織以下遷移文件:

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 

而對於Actioncodes我有遷移文件:

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 

組織模型文件包括:belongs_to :actioncode

雖然actioncodes模型文件包含:has_many :organizations

任何想法可能導致錯誤消息?

如果我從遷移文件中刪除index: true, foreign_key: true,它將遷移而不會出錯。並且當我用不正確的行t.references :actioncode_id, index: true, foreign_key: true替換那行時,它會給出下面的錯誤,最後一行(「ids」)表明Rails以某種方式似乎與表名有關的問題?

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

表名是actioncodes。我已將其遷移文件添加到原始文章 – Nick

+1

看起來'CreateOrganizations'遷移正在執行'CreateActioncodes'之前運行。 - 'CreateActioncodes'將首先運行,從而確保'actioncodes'表存在。 –

+0

你可能會建議我應該如何改變它?我檢查並確認SQL代碼確實在Actioncodes之前創建了組織。 – Nick

回答

13

所以問題發生,因爲執行CreateActioncodes之前CreateOrganizations遷移正在運行。

CreateActioncodes將首先運行,從而確保存在action codes表。

遷移的運行順序基於遷移的時間戳 - 如文件名所示。 20141014183645_create_users.rb將在20141014205756_add_index_to_users_email.rb之前運行,因爲第二個的時間戳 - 20141014205756在第一個的時間戳之後 - 20141014183645

確保CreateOrganizations遷移的時間戳在CreateActioncodes遷移的時間戳之後。

您可以手動更改文件名中的時間戳。或者刪除這些遷移文件,並以正確的順序創建它們。

+0

這工作!我使用'rails生成遷移AddActioncodeToOrganizations actioncode:references'來爲參考創建一個新的遷移文件。刪除了舊的遷移文件(我爲其他變量保留)的引用。 @mu的回答太短,當然也是對的,但@Prakesh只是早一點,所以我接受了這個解決方案。 – Nick

+0

謝謝 - 在生成db模型時容易被忽視的東西 – Onichan

9

在此行中的foreign_key: true

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

告訴Rails來創建數據庫中的外鍵。一個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.

所以它是數據庫(它屬於的地方)裏面的一些邏輯,以確保你不能把無效值在actioncode列,你不能刪除從actioncodes表是項在其他地方使用。

爲了創建約束,引用表(actioncodes)需要存在,然後再引用它。看起來您的遷移正試圖在actioncodes之前創建organizations,因此您只需重命名CreateOrganizations遷移文件,以便其時間戳前綴位於CreateActioncodes之後。前綴只是格式爲YYYYMMDDhhmmss的時間戳,因此請將CreateOrganizations時間戳更改爲CreateActioncodes時間戳,再加上一秒鐘。

3

我也遇到了這個錯誤。如果您使用測試數據庫運行rspec,請確保在運行rspec之前在終端中運行[rake db:test:prepare]

相關問題