学習記録

アウトプット用に作りました

モデルのポリモーフィック関連付け

ポリモーフィック関連付けを使うと、ある一つのモデルが他の複数のモデルに属していることを、一つの関連付けだけで表現することができます。


ポリモーフィック関連付け

市内の学校の情報を管理するアプリを想定します。

f:id:kimura34:20210429135918p:plain

まず最初に赤枠で囲った部分を説明していきます。
TeacherモデルとStudentモデルは両方ともSchoolモデルと関連しています。
Schoolモデルのschoolable_typeにはTeacher、Studentのクラス名が入ります。schoolable_idにはteacher、studentの各idが入ります。
これをポリモーフィック関連で実装していきます。ではモデルを定義していきましょう。

class School < ActiveRecord::Base
  belongs_to :schoolable, polymorphic: true, dependent: :destroy
end
class Teacher < ActiveRecord::Base
  has_one :school, as: :schoolable, dependent: :destroy
end
class Student < ActiveRecord::Base
  has_one :school, as: :schoolable, dependent: :destroy
end

Schoolモデルは、複数のモデルTeacher、Studentに属していることを1つの関連付けのschholableだけで表現できています。

@teacher.schoolとすればTeacherモデルからschoolの情報を取得できます。また@school.schoolableとするとTeacherかStudentの中の指定した誰かを取得することができます。
参考 : Active Record の関連付け - Railsガイド


中間テーブルとポリモーフィック関連を組み合わせる

今回の場合、CityモデルはSchoolモデルを中間テーブルとしてTeacherとStudentモデルと関連を持っています。 f:id:kimura34:20210429141130p:plain

この時のCityモデルの定義は下記のようになります。

city.rb

has_many :schools
has_many :teachers, through: :schools, source: :schoolable, source_type: 'Teacher'
has_many :students, through: :schools, source: :schoolable, source_type: 'Student'

through中間テーブルのモデルを指定しています。
source中間テーブルの先の関連モデルを指定しています。
source_typeポリモーフィック関連のソースのタイプ、つまりSchoolのschoolable _typeを指定しています。

またTeacher、StudentモデルでもCityモデルへの関連を定義します。

has_one :city, through: :schools

これにより@teacher.cityで先生のcity情報を取得できるし、@city.studentsでcityの生徒情報を扱うことができるようになります。
参考 : Active Record の関連付け - Railsガイド