【Rails】あるテーブルからあるテーブルへ、belongs_toを「複数回」使いたい


関連付けアンチだったけど、今は好き。「コロンが付いたら配列を疑え」の意識がまた消えてた。でもモデルに関しての知識が深まったから良し(?)。普通にreferences使わない方が簡単。

【ページ内リンク】

0.環境
1.動機
2.やった
3.foreign_key: trueを設定する理由
4.感想
5.参考文献

0.環境

・AWS
・heroku/7.48.0 linux-x64 node-v12.16.2
・Rails 5.2.4.5
・ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
・MySQL 5.7.31
・PostgreSQL 9.2.24

1.動機

試合のテーブル(Gameテーブル)を作っている。試合なのでホームチームとビジターチームの2種類のチーム名が必要。Teamテーブルと関連付けしたいが、Gameテーブルhometeam_idvisitorteam_idを作った場合、belongs_toTeamテーブルidとどうやって関連付けすればいいんだ・・・?と思ったため

ページ内リンクへ戻る

2.やった

【やりたいこと】
①カラム名をhometeam_idvisitorteam_idとする
②外部キー制約
game.hometeam.~で値が取れるようにする
④値がnullでもOKとする

20210402000000_create_games.rb
class CreateGames < ActiveRecord::Migration[5.2]
  def change
    create_table :games do |t|
      t.references :hometeam, foreign_key: { to_table: :teams }
      t.references :visitorteam, foreign_key: { to_table: :teams }

      t.timestamps
    end
  end
end

t.references :hometeamで、hometeam.idの値を参照しますよという意味(しかし、そんな物は無い。) #①完了
foreign_key: { to_table: :teams }は、foreign_key: trueを変形したもの。なぜtrueだと駄目なのかは、t.references :hometeam, foreign_key: trueだとhometeamテーブルと外部キー制約をするということになる。しかしそんなテーブルは存在せず、teamテーブルを参照する必要があるから。 #②完了

game.rb
class Game < ApplicationRecord
  belongs_to :hometeam, class_name: "Team", optional: true
  belongs_to :visitorteam, class_name: "Team", optional: true
end

optional: trueは下記参照。 #④完了(?)
belongs_to :hometeamgame.hometeamとしたときに値が取れるようにし、class_name: "Team"で値はteamテーブルから取りましょう。という意味。】 #③完了

ページ内リンクへ戻る

3.foreign_key: trueを設定する理由

外部キー制約をするため。

 foreign_key: trueが無い場合を考える。referencesクラスとすると、値が親テーブルに無かったりnullの場合にエラーを出す。
 値がnullでもOKとしたい場合optional: trueを入れるが、これだと親テーブルに無い値の時にもエラーを吐き出さずに通してしまう。
 foreign_key: trueを入れることで、親テーブルに無い値の時はエラー、nullはOKとなる。

値がnullでエラーとするときの存在価値は正直分からなかった。referencesと役割が被っているのか、それとも何か別の理由があるのだろうか。もしくは自分がただ勘違いしているのか。

ページ内リンクへ戻る

4.感想

③について思ったこと。
普段はbelongs_to :teamのように関連付けを行っているけど、これってclass_nameを指定しない場合は自動でclass_name: "Team"となってるだけなのかな。何でTeamテーブルを参照しているのにbelongs_to Teamじゃないんだろうと思ってたけど、なるほど合点がいった。Railsすごい(n回目)

ページ内リンクへ戻る

5.参考文献

参考1:Railsで外部キー制約のついたカラムを作る時のmigrationの書き方
参考2:Active Record の関連付け

ページ内リンクへ戻る