移行時に、次のエラーメッセージが表示されます。
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
そして、アクションコードの場合、移行ファイルがあります。
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")
したがって、CreateOrganizations
が実行される前にCreateActioncodes
移行が実行されているため、この問題が発生しています。
CreateActioncodes
が最初に実行され、それによってaction codes
テーブルが存在することを確認します。
移行が実行される順序は、ファイルの名前に示されているように、移行のタイムスタンプに基づいています。 20141014183645_create_users.rb
は、2番目のタイムスタンプとして20141014205756_add_index_to_users_email.rb
の前に実行されます-20141014205756
は最初のタイムスタンプの後にあります-20141014183645
。
CreateOrganizations
移行のタイムスタンプがCreateActioncodes
移行のタイムスタンプの後にあることを確認してください。
ファイル名のタイムスタンプを手動で変更することもできます。または、これらの移行ファイルを削除して、正しい順序で作成します。
foreign_key: true
この行:
t.references :actioncode, index: true, foreign_key: true
Railsデータベース内に外部キーを作成するように指示します。A 外部キー :
制約は、列(または列のグループ)の値が別のテーブルのある行に表示される値と一致する必要があることを指定します。これにより、2つの関連するテーブル間の参照整合性が維持されると言います。
したがって、actioncode
列に無効な値を入れたり、他の場所で使用されているactioncodes
テーブルからエントリを削除したりできないようにするのは、データベース(データベースが属する)内のロジックです。
制約を作成するには、参照する前に、参照されるテーブル(actioncodes
)が存在している必要があります。移行がorganizations
の前にactioncodes
を作成しようとしているようです。そのため、CreateOrganizations
移行ファイルの名前を変更して、タイムスタンププレフィックスがCreateActioncodes
のプレフィックスの後に来るようにするだけです。プレフィックスはYYYYMMDDhhmmss形式のタイムスタンプであるため、CreateOrganizations
タイムスタンプをもう1秒でCreateActioncodes
タイムスタンプに変更します。
私もこのエラーが発生していました。テストデータベースを使用してrspecを実行している場合は、rspecを実行する前に、ターミナルでrake db:test:prepare
を実行していることを確認してください。