2013-04-27 22 views
28

私はレールが新しく、一晩中不運にもこれを解決しようとしています。レールモデルに外部キーを追加する

私はusers,businesses、およびbusiness_hoursという3つのモデルを作成しました。私は関連団体(business_hours belongs_to businesses which belongs_to users)と(user has_one business which has_many business_hours)も追加しました。

ドキュメントをオンラインで読むと、私のDBテーブルにこれらの関係のための外部キーを作成する必要があるようです。どのようにRails ActiveRecordの移行を使用してこれを行うのですか?私は私のDBとしてPostgreSQLを使用しています。

答えて

23

まず、belongs_toメソッドを使用するときは、単語の末尾にsを使用しないでください。business_hours belongs_to business which belongs_to user

今すぐ移行を作成します。

rails generate migration migration_name 

そして移動中には列を追加:

class MigrationName < ActiveRecord::Migration 
    def change 
    add_foreign_key :business_hours, :businesses 
    add_foreign_key :businesses, :users 
    end 
end 

実行rake db:migrate。それでおしまい。

+0

を作成

add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id" 

? –

+0

私がdb:migrateを実行すると、私はこのエラーになります:PG :: Error:ERROR:relation "business"は存在しません –

+0

def changeメソッドで私のエラーが見つかりました。ご協力いただきありがとうございます! –

5

私はPostgreSQLで試していませんが、少なくともMySQL Railsでは外部キーを作成しません。実際のDBレベルの外部キーではありません。彼らが作成するのはすべて、慣習に従って命名された整数です。つまり、すぐに使用すると、この偽の外部キーの索引を取得せず(高速検索のため)、dbレベルの参照整合性チェックもありません。あなたは「実行」関数に文字列引数として渡すことができRailsのマイグレーションでは

ALTER TABLE your_table ADD CONSTRAINT fk_whatever_you_want_to_name_it FOREIGN KEY (foreign_key_name) REFERENCES another_table(its_primary_key) 

:あなたのような何かをする必要があることを取得します。 「実際の」外部キーを追加すると、自動的に索引も作成されます。少なくとも私にとっては、これはむしろ厄介な驚きでした。

+0

これは私にとってニュースです。私は他の誰かがそれについてコメントしてもらいたいと思います。これは本当に厄介な驚きです。私はPostgresを使用し、pgAdminのテーブルを見ると、どちらも外部キーとしてリストされません。これは、Railsのみのプロジェクトでは問題ありませんが、データベースにアクセスするために他のプログラムが必要な場合はどうすればよいですか? – tentimes

+0

少し厄介ですが、その背後にも理由があることがわかりました。 RailsはDBから抽象化しようとしているので、永続化レイヤーを簡単に切り替えることができます。しかし、私はそれが十分に強調されていないと思う。必要に応じて、外部キーとして必要なフィールドで常にadd_indexを使用できます。あるいは、SQLでマイグレーションを書くこともできますし、外部キーを何とかするように強制することもできます。しかし、あなたがレールが最初にそれをしていないことを知らなければ、あなたはそれを行う方法を探すことさえありません。それは実際に理にかなっていますか? :-) – Renra

+0

実際に私は、これを修正するために外国人と呼ばれる宝石があることを知った!それはまたあなたのデータベース全体のために働く、移民と呼ばれるアドオンの宝石を持っています。インデックスを追加すると、何かが外部キーとしてマークされますか?私はそれを知らなかった - 私はレールに新しいです;) – tentimes

54

これに対して現在受け入れられている回答は、データベースの外部キーを追加しないため、実際には正確ではありません。整数列を追加するだけです。 のRails 4.2.xでは

、現在のアプローチは次のとおりです。

http://guides.rubyonrails.org/active_record_migrations.html#foreign-keys

移行を作成します。既存の列については

rails generate migration migration_name 

を、移行には、外部キーを追加しますこのように:

class MigrationName < ActiveRecord::Migration 
    def change 
    add_foreign_key :business_hours, :businesses 
    add_foreign_key :businesses, :users 
    end 
end 
Railsの4.xののためにか、 新しい列を追加すると、それはあなたがこれを行うことができ、外部キーになりたい、あなたはおそらくも真としてインデックスを指定したい場合は、それが一部ではありませんしている場合

外部キーの要件の:

http://edgeguides.rubyonrails.org/active_record_migrations.html#creating-a-migration

class MigrationName < ActiveRecord::Migration 
    def change 
    add_reference :business_hours, :business, index: true, foreign_key: true 
    add_reference :businesses, :user, index: true, foreign_key: true 
    end 
end 
+1

このChrisを共有してくれてありがとう。私はこれを理解するために全部を見た。 – mack

+0

これは私がこの問題の解決策を探すときに期待していたことです。 – Ratinahirana

+1

このような外部キー列の名前を指定する方法はありますか?私はすでに、特定のデータテーブルに対して同じレコード内に複数の参照がある状況がありました。つまり、私は(sourceClass、targetClass、fieldName)を見ることを期待していますが、上記の例では(sourceClass、targetClass)しか含まれていないようです。誰かにこれについての情報がありますか? –

2

レール5は今http://devdocs.io/rails~5.0/activerecord/connectionadapters/schemastatements#method-i-add_foreign_keyを参照して、移行中に外部キーを追加することができます。あなたが行うことができます非標準データモデルを持っているので、もし

add_foreign_key :articles, :authors 

ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id") 

を作成します。彼らはすでにそれを持っていない場合、私はまた、ユーザーに企業へbusiness_id列とUSER_ID列を追加する必要があります

ALTER TABLE "articles" ADD CONSTRAINT fk_rails_58ca3d3a82 FOREIGN KEY ("author_id") REFERENCES "users" ("lng_id") 
関連する問題