再・ポリモーフィック関連について
ポリモーフィック関連とは
ポリモーフィック関連とは、ある1つのカラムが複数のテーブルを参照しているようなパターンの関連を表したものです。
同じようなカラムを持っているテーブルが複数ある場合、それらを1つのテーブルで管理してしまうことができます。複数のクラスのインターフェースを統一し、同じように扱えるようになります。
メリット
・どのクラスに属するものかを意識することなく関連するレコードにアクセスできます。
・特定の外部キーを持たず、1つのカラムで複数のテーブルを管理しているため、新たに管理するモデルが増えたとしてもカラムを追加したり、テーブルを追加することなく、has_manyの関連を定義してやるだけでよいです。
ポリモーフィック関連を使わなかった場合
外部キーを関連するモデルの数だけカラムとして増やす or テーブルを増やす必要があります。
*外部キーを関連するモデルの数だけカラムとして作った場合のデメリット
→新たにタイムラインが従属するモデルを作った際、タイムラインのbelongs_toを増やし、カラムも追加しないといけなくなります。
→タイムラインモデルのインスタンスから直接、従属しているモデル(questionなのかanswerなのか)を判断することができません。
*関連するモデルが増えるとテーブルの数もどんどん増えていくことになります。
具体例
Food、Shopというモデルがあるとします。それぞれにReviewモデルをポリモーフィック関連で紐づけたい場合、以下のように定義してあげることが出来ます。
review.rb
class Review < ApplicationRecored
belongs_to :comment, polymophic: true
end
カラム
・id
・comment_id
・comment_type
・text
food.rb
class Food < ApplicationRecord
has_many :reviews, as: :comment
end
カラム
・id
・name
shop.rb
class Shop < ApplicationRecord
has_many :reviews, as: :comment
end
カラム
・id
・name
こうすることで、以下のようにReviewクラスのインスタンスから、どのモデルと紐づいているのか意識することなく、関連先のインスタンスの情報を作成・取得することが出来ます。
#レコード作成
food = Food.create(name: "potato")
food.reviews.create(text: "good")shop = Shop.create(name: "familymart")
shop.reviews.create(text: "my favorite store")
shop.reviews.create(text: "it is exiting")
#レコード取得
food.reviews.each do |review|
puts review.text
end=> potato
shop.reviews.each do |review|
puts review.text
end=> my favorite store
=> it is exitingReview.all.each do |review|
puts review.comment.name
end=> potato
=> familymart
=> familymart