0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

関連付けアンチだったけど、今は好き。「コロンが付いたら配列を疑え」の意識がまた消えてた。でもモデルに関しての知識が深まったから良し(?)。普通に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 の関連付け

ページ内リンクへ戻る

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?