Railsの移行:別の名前のt.references?


121

だから私は学校のコースのためにこのようなcreate_tableを持っています:

create_table :courses do |t|
  t.string :name
  t.references :course
  t.timestamps
end

しかし、私はそれが他の2つのコースを参照することを望んでいます:

has_many :transferrable_as # A Course
has_many :same_as          # Another Course

次のように言ってもいいですか?

t.references :transferrable_as, :as=> :course

回答:


161

これはすべて、最初の移行/列定義で行うことができます(少なくとも現在はRails 5で)。

t.references :transferable_as, index: true, foreign_key: {to_table: :courses}
t.references :same_as, index: true, foreign_key: {to_table: :courses}

10
これはRails 5.1で機能し、他の提案では機能しません。ずっとすっきりしていて、気持ちいいです。
スティーブンマードック2017年

2
Rails 5.1.4を使用していますが、機能しません。foreign_keyこのようにテーブル作成でオプションを指定すると、作成しているテーブル自体が存在しないというエラーが発生します...したがって、公式のAPIでは実際にはサポートされていないようです。
Quv

3
私はまた、その読みindexすでにRailsののような外部キーに追加されstackoverflow.com/questions/39769981/...
ジョナサン・レイエス

98

あなたはこの方法でそれを行うことができます:

create_table :courses do |t|
  t.string :name
  t.references :transferrable_as
  t.references :same_as
  t.timestamps
end

またはt.belongs_toのエイリアスとして使用t.references

foreign_key: trueこれらの2つの参照行に追加することはできません。それらをデータベースレベルで外部キーとしてマークする場合は、次のように移行する必要があります。

add_foreign_key :courses, :courses, column: :transferrable_as_id
add_foreign_key :courses, :courses, column: :same_as_id

更新

Rails 5.1以降では、次のようにcreate_tableブロックの移行に外部キーを追加できます。

create_table :courses do |t|
  t.string :name
  t.references :transferrable_as, foreign_key: { to_table: 'courses' }
  t.references :same_as, foreign_key: { to_table: 'courses' }
  t.timestamps
end

5
foreign_key: true参照行に追加できないことに関する部分は、私をつまずかせていたものでした。を追加し、add_foreign_keyそれらの列名を指定するとうまくいきました。
マシュークラーク

これはRailsでそのまま動作しますか?stackoverflow.com/a/22384289/239657によると、これにはschema_plusgem が必要です。Railsのadd_reference docsには、:referencesオプションは含まれていません。
Beni Cherniavsky-Paskin

1
私が何を以下のいないよreferences:とは対照的に、オプションが(ためであるt.referencesFOREIGN_KEY配慮した、唯一のモデルレベルでの関連ではないことによっての世話をしているadd_foreign_key
MCB

1
@MCB t.referencesは、「このテーブルに、別のテーブルの主キーであるフィールドを追加する」と言います。このreferences:オプションは、どのテーブルが主キーであるかを示します(フィールドの名前で明確でない場合に必要です)。このadd_foreign_key関数は、ここで参照整合性を強制するようにデータベースに指示します。
Toby 1 Kenobi

2
@MCB結局のところ、私はあなたがずっと正しかったことを理解しています。上記の最初のコメントは正確です。これらのadd_foreign_key行は、何をどの外部キーであるかをデータベースに通知します。references:パラメータは何もしません。
トビー1ケノービ2018

13

このスレッドには、Rails風の別の方法があると思います: Scaffolding ActiveRecord:同じデータ型の2つの列

移行中:

t.belongs_to:transferrable_as

t.belongs_to:same_as


1
しかし、dbはどのようにテーブルをリンクする外部キーを知っていますか?私はこれをPostgresデータベースでPG::UndefinedTable: ERROR試していますが、存在しないテーブルに外部キー制約を追加しようとするとエラーが発生します。
Toby 1 Kenobi 2015

誰かが不思議に思っている場合、belongs_toは単なるエイリアスreferencesあり、まったく同じ機能を持っています。
Jason Swett、2018

11

この質問に対する追加の回答として、関連付けを完了するには、モデルに次の行が必要です。

    belongs_to :transferrable_as, class_name: "Course"
    belongs_to :same_as, class_name: "Course"

3

オプションをreferences受け入れないと思いますが、:as手動で列を作成できます...

create_table :courses do |t| 
  t.string  :name 
  t.integer :course1_id
  t.integer :course2_id 
  t.timestamps 
end 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.