目標
has_manyの関連付けを作成するときに、
どちらのモデルに対してforeign_keyを指定するべきか
わからず調べたものの、その説明すらわかりにくかったので
自分なりの解釈を載せていこうと考えた。。
疑問
今、User has_many cupsという関係を作りたいとする。
[モデルの関係]
User
↓
↓ has_many
↓
Cup
// Cupとはコーヒーカップのことでここでは「コーヒー」という意味
// User has_many cupsってお前一日に何杯飲むねんって感じだけど。。
この場合、UserとCup、どっちのマイグレーションファイルに
foreign_keyを記載すればいいの?
そもそもforeign_keyってなんなのかわかってないなあ。調べよ
foreign_keyとは?(わかりにくい)
参照先を参照するための外部キーの名前を指定するもの
※以下より引用
http://railsdoc.com/references/belongs_to
わかりづれ〜〜〜(^ー;)
参照先を参照するって、
has_manyで参照する場合を示すのか、
belongs_toで参照する場合を示すのか
どっちよこれ。。
改めてforeign_keyとは?(わかりやすい)
ズバリ言うと(結果論)、この文脈においてはbelongs_toで参照する場合を示す。
従って、先ほどの文は
(belongs_toによって)参照先を参照するための外部キーの名前を指定するもの
という解釈になる。
加えて、相手(参照先)の外部キーの名前を指定するものってことだから、
それはbelongs_toを行う側に記述しなければいけないってことも読み取れる。
よって、この文は
belongs_toで参照する相手(参照先)の外部キーを指定するために、
belongs_toを行う側に記述しなければならないもの
と解釈できる。
マイグレでforeign_keyを指定する際の注意点
マイグレーションファイルの作成時に、
foreign_keyの指定をするコードには、
def change
create_table AAAA do |t|
t.references BBBB, foreign_key: true
end
end
とか
def change
add_reference AAAA, BBBB, foreign_key: true
end
という形をとるものがあり、どちらも
テーブルAAAAに、 モデルBBBBのforeign_key(= BBBB_id) を追加する
と解釈される。
しかしこれだと、このBBBB_idを追加したものの、
それをhas_manyで参照するのか、
belongs_toで参照するのかって話になる。
先ほどのforeign_keyの話に戻すと、
foreign_keyは、belongs_toを行う側に記述しなければならないものであった。
上記のコードでは、create_table AAAAという記載から
AAAAというテーブルにBBBBへのforeign_keyを指定する
という意味になるので、
AAAA belongs_to BBBB
という関係になっていることがわかる。
そしてこれは
BBBB has_many AAAA
という関係でもある。(has_manyの場合は)
結論
つまり、BBBB has_many AAAAという関連付けをしたい場合、
foreign_keyはAAAAに指定しなければいけないということ。
(正確に言うと、AAAAのテーブルを編集するマイグレファイルに記述しなければならない)
理由は(くどいが)、foreign_keyはbelongs_toで参照を行う側に記述しなければならないため、
上記関連付けをAAAA belongs_to BBBBという形に直したときに、
belongs_toを行っているのはAAAAなので、AAAA側に記述する。
ちなみに(追記)
foreign_keyを記述してrails db:migrateをすると、
foreign_keyを記述した側のモデル.rbに自動的にbelongs_toが記述されます。
(has_manyに関してはもう片方のモデル.rbに手で記述しなければなりません)
このことからも、foreign_keyはbelongs_toで参照するという前提が正しいことがわかりますね。
終わり