2016-09-18 7 views
2

と結合私は自分がモデルと呼ばれるセクションに参加してい:マイグレーションファイルをRailsの - 自己は、PostgreSQL

class Section < ApplicationRecord 
    belongs_to :offer 
    # Self joins: 
    has_many :child_sections, class_name: "Section", foreign_key: "parent_section_id" 
    belongs_to :parent_section, class_name: "Section", optional: true 
end 

を:MYSQLでの作業

class CreateSections < ActiveRecord::Migration[5.0] 
    def change 
    create_table :sections do |t| 
     t.string :name 
     t.references :offer, foreign_key: true 

     t.references :parent_section, foreign_key: true 
     t.timestamps 
    end 
    end 
end 

は大丈夫だったが、その後、私は、データベースを落とし、それらを変更postreql(彼らは英雄的なのでフレンドリーです)に、新しいものを作成しました。 rails db:migrateを試した後、次のようなエラーが表示されます。

StandardError: An error has occurred, this and all later migrations canceled: 

PG::UndefinedTable: ERROR: relation "parent_sections" does not exist 

何が起こった可能性がありますか? mysqlとpostgresqlのself joinの間に違いはありますか?

答えて

3

あなたt.referencesコール:

t.references :parent_section, foreign_key: true 

は、PostgreSQLとの二つのことをしようとします:

  1. parent_section_idと呼ばれる整数列を追加します。
  2. データベース内にforeign key constraintを追加すると、参照整合性が確保されます(つまり、parent_section_idの値が存在することを確認してください)。

です。 t.references :parent_sectionについて、FKは、次のようになります。

parent_section_id integer references parent_sections(id) 

それが命名規則標準のRailsを使用していますので、あなたのparent_sectionsエラーはどこから来る、というのです。あなたはbelongs_to:class_nameを供給できるだけのようなFK制約のためにターゲット表を指定することができます。

t.references :parent_section, :foreign_key => { :to_table => :sections } 

このあなたの次の問題をトリガー修正:あなたは存在しないテーブルへのFKを作成することはできませんし、ブロックはブロックcreate_table :sectionsが完了するまで存在しません。

この問題には2つの一般的な解決策があります。

  1. は、すべての列を持つテーブルを作成し、FK制約を追加します。あなたの移行では、このような何か:

    create_table :sections do |t| 
        t.string :name 
        t.references :offer, foreign_key: true 
        t.references :parent_section 
        t.timestamps 
    end 
    add_foreign_key :sections, :sections, :column => :parent_section_id 
    
  2. が参照する列(parent_section_id)せずにテーブルを作成し、後に参照する列とFKを追加します。あなたの移行では、このような何か:

    create_table :sections do |t| 
        t.string :name 
        t.references :offer, foreign_key: true 
        t.timestamps 
    end 
    change_table :sections do |t| 
        t.references :parent_section, :foreign_key => { :to_table => :sections } 
    end 
    
+0

どのような素晴らしい答え!私は家に帰るとすぐにこれを試みます。私が追加したいのは、db:resetを実行した後にエラーが消えてしまったことですが、その後もマイグレーションを実行できませんでした。 – Ancinek

+1

@Ancinekこれがあなたのために働いた場合、回答を受け入れるようにしてください。あなたの問題を解決した答えを受け入れることは、SOの良い習慣と "良いこと"です。そのようにすることで、問題を解決したソリューション**を提供したユーザーとコミュニティーに知らせるユーザーの両方に報酬を与えます。 –