【結論】
・テーブル間の多対多の関係を表す関連付けとして、has_many throughと、has_and_belongs_to_manyが存在する
・has_many throughは、中間テーブルのモデルに何らかの処理を記述したい場合に用いる
・has_and_belongs_to_manyは、中間テーブルのモデルに何らかの処理を行う必要が無い場合に用いる
【目次】
【本題】
多対多を表す関連付け
Railsのアソシエーションにおいて、多対多の関係を表す関連付けは二種類存在します。 今回は、それらの違いについては、解説します
共通点
いずれにも共通している点としては、「中間テーブル」の存在です。
一対一や一対多であれば、所属する側のテーブルに外部キーを持たせる事で、どのデータと紐付いているか判別が可能でした。 しかし、多対多だと、一つのデータに複数データが紐付いているという状況が双方で発生するので、外部キーを保存するカラムを増やしていかないと、どのデータと紐付いているか判別できません。
そこで登場するのが「中間テーブル」です。 中間テーブルは、多対多の関係性を持つテーブルの間に位置し、双方の外部キーを持つ事で、どのデータと紐付いているか特定が可能になります。
これにより、カラムを増やさずとも、レコードを増やすだけで、複数のデータの関連付けに対応出来る様になっています。
なおER図にすると、下記の様な内容です。
has_many through
has_many throughは、下記の様にモデルで関連付けを行います。
class Post < ApplicationRecord has_many :poststocks has_many :users, through: :poststocks end class PostStock < ApplicationRecord belongs_to :post belongs_to :user end class User < ApplicationRecord has_many :poststocks has_many :posts, through: :poststocks end
中間テーブルに位置するモデルに、双方への所属を表す関連付けを記述するのが特徴です。
has_and_belongs_to_many
has_and_belongs_to_manyは、下記の様にモデルで関連付けを行います。
class Post < ApplicationRecord has_and_belongs_to_many :users end class User < ApplicationRecord has_and_belongs_to_many :posts end
中間テーブルに位置するモデルには何も記述しないのが特徴です。
使い分け
has_and_belongs_to_manyは、中間テーブルのモデルが不要な為、中間テーブルのモデルに何らかの処理を記述する必要が無い場合に、最もシンプルで最適だと言えます。
逆にhas_many throughは、中間テーブルのモデルが必要ですが、中間テーブルを単なる関連付けの橋渡しでなく、ここに保存される情報も一つのデータとして扱いたい場合に採用される関連付けたと考えています。
例えば、「ユーザー」が「記事」に対して「いいね」する機能を実装する場合などです。 この場合、「いいね」の数も集計したりと、中間テーブルの情報自体にもデータとしての意味が出てくるので、has_many throughが最適だと言えます。
参考情報
Active Record の関連付け (アソシエーション) - Rails ガイド
《今日の学習進捗(3年以内に10000時間に向けて)》
学習開始からの期間 :149日
今日までの合計時間:1453h
一日あたりの平均学習時間:9.8h
今日までに到達すべき目標時間:1361h
目標との解離:92h
「10,000時間」まで、
残り・・・「8547時間!」