LoginSignup
3
2

More than 5 years have passed since last update.

多対多の関連付けについてのまとめ

Last updated at Posted at 2017-11-03

RailsでDBを構築する際によく使用される「多対多の関連付け」について。

has_many :through

とある病院の診療予約管理システムを考える。

患者(patient.rb)と医師(Physician.rb)は多対多の関係性にある。1人の患者は複数の医師にかかっているだろうし、1人の医師もまた複数の患者を診察している。

このとき、患者と医師は予約情報(Appointment.rb)を介して関連付けするとスムーズになる。

patient.rb
class Patient < ApplicationRecord
  has_many :appointments
  has_many :physicians, through: :appointments
end
physician.rb
class Physician < ApplicationRecord
  has_many :appointments
  has_many :patients, through: :appointments
end
appointment.rb
class Appointment < ApplicationRecord
  belongs_to :physician
  belongs_to :patient
end

多対多の関連付けは、上記のようなソースコードで記述される。

先述したように、ここで特徴的なのはPatientモデルとPhysicianモデルは、直接的な関連付けがなされていないという点。

スクリーンショット 2017-11-03 3.26.31.png
(RailsGuideより抜粋:https://railsguides.jp/association_basics.html#has-many-through%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91)

ここでappointmentsテーブルは、physiciansテーブルとpatientsテーブルの間に入っているため、中間テーブルと呼ばれます。

また、Appointmentモデルのように、2つのモデルの中立ちを行うモデルを結合モデルと呼びます。

SNSアプリケーションにおける多対多

多対多関連付けは2つの独立したモデルを、第3のモデルを介して関連付けます。

Railsチュートリアルなどで作成するサンプルアプリケーションでは、twitterのようにユーザーをフォローする機能を実装する。

フォローするユーザーAとフォローされるユーザーBは、どちらも同じUserモデル。

また、ユーザーAはユーザーBをフォローしているものの、ユーザーBはユーザーAをフォローしていない可能性がある。そのため、図のように新たにRelationshipモデルを作成し、フォロー情報を管理する必要がある。

image.png

こうすることにより、1人のユーザーAが複数のユーザーを、relationshipテーブルを介してフォローしているという状態を作り出すことが出来る。

user.rb
class User < ActiveRecord::Base
  has_many :microposts, dependent: :destroy
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed

 #( 中略 )

end
3
2
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
3
2