🔥

[Rails]中間テーブルの役割について

2023/03/08に公開

以前、中間テーブルについては、follow/follower機能作成 N:Nで少しやったが
今回はそれよりさらに深めていこう。

中間テーブルの役割とは

中間テーブルの役割は大きく2つ。

  1. 多対多の関係を表現するためのもの
  2. 結合条件としての役割を果たすもの

<中間テーブルの特徴>

  • それぞれのテーブルの主キーを外部キーとして持ち、両方のテーブルを参照
    =>接続している2つのテーブルのForeign_keyを持っている。
  • それぞれのテーブルのレコードを組み合わせて、多対多の関係を表現する。
     (=>多:多を中間テーブルを作成することにより1:Nにしている。)
  • null(空)を出すことなく、レコードを追加することができる。

主な用語の説明

用語 意味 補足
リレーションシップ(relationship) 繋がり ここでは、テーブル同士の繋がり(関連)のこと
主キー(PK:Praimary Key) primary:最初の テーブルの情報を一意に識別するためのもの
外部キー(foreign key) foreign: 外国にある 関連したテーブル間を結ぶために設定する列のこと
アソシエーション(association) 繋がり、関連性 異なる 2 つのモデルの間に、1:N の関連性を持たせるもの

association

1 . belongs_toメソッド
他のモデルに属している事を定義。

  1. has_manyメソッド
    他のモデルを複数持っている事を定義。

has_manysでよく使用するオプションについて

:class_name

  • 関連するクラスの名前を指定するもの。

ex.) follow/follwer機能でいくと…
"followするuser" と "followされるuser" どちらもUserなので
中間テーブルの作成(relationとする)にて以下のように定義する場合に使用される。

<relation.rb>

カラム名
id integer 主キー (PK)
follower_id(class_name:"User") integer フォローするユーザのid
followed_id(class_name:"User") integer フォローされるユーザのid
<relationship.rb>
class Relationship < ApplicationRecord
	 belongs_to :follower, class_name: "User"
	 belongs_to :followed, class_name: "User"
end
  • 関連するモデルの名前を指定するために使用と記述したが、
    followerもfollowedも関連モデルはuserなのでclass_name:"User"のように定義する必要があるのだ。

:foreign_key

  • 外部キーのカラム名を指定するもの。
  • 外部キーの中でも、外部キーのカラム名が、関連するモデルの名前と異なる場合に使用する!

ex. )上記のfollow/follwerをまた使用すると…
上記ではrelationモデルに定義したが今度はuser modelにも記述していく

<user.rb>

:
has_many :follower, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy # ① フォローしている人の取得
has_many :followed, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy # ② フォローされているの人取得
:

このように記述していく。上記relation.rbでfollowedとfollwerを作成したがこれらはモデル名と異なっているから:foreign_keyを使用している。

:dependent

  • 関連するオブジェクトの削除方法を指定する。

  • has_manyでdependent: :destroyをつけると
    親モデルが削除された場合に、関連付けられた子モデルも同時に削除されるようになる。

  • dependent: :destroyをつけない場合は、
    親モデルが削除されても、関連する子モデルは削除されない。

親モデルが削除された場合に、その子モデルも一緒に削除されるようにする
というのは、データの整合性を保つことができると言うこと。


以上!

Discussion