目標
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で参照する
という前提が正しいことがわかりますね。
終わり