Railsのポリモーフィック関連を使って多対多を実現する
個人開発として金沢観光情報サービスのhttps://notear.netを開発中にポリモーフィック関連でコードをすっきりさせたかったのでそのときに調べたことを書きます。
ポリモーフィズムとは
オブジェクト指向の3大要素
カプセル化、継承と並ぶ、オブジェクト指向の3大要素のうちの一つです。
ダックタイピング
“If it walks like a duck and quacks like a duck, it must be a duck”
「もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである」
ja.wikipedia.org/wiki/%E3%83%80%E3%83%83%E3%82%AF%E3%83%B…
オブジェクトの実態が違っても、決まった振る舞い(同じメソッドを呼び出すなど)をすることで、同じオブジェクトとして扱えることです。
いちいちオブジェクトの実態のことを考えてコードを書いていたらコードは汚くなるし、大変です。 メソッド(命令)を全部同じ名前で使えば、その内容についてはオブジェクトごとに勝手に変わっても大丈夫になります。
ポリモーフィック関連
ポリモーフィック関連とは、このポリモーフィズムを使ってモデルを関連づけることを言います。
やりたかったこと
例えばnotear.netでは、Cafe(カフェ)とSpot(観光スポット)をタグで検索できる機能をつけようと思いました。1つのSpotあるいはCafeに対して複数のSearchTag(タグ)が付随するようになります。
このときに、ポリモーフィックを使わないと、
class Cafe < ApplicationRecord
has_many :search_tags, through: :cafe_search_tags
has_many :cafe_search_tags
end
class Spot < ApplicationRecord
has_many :search_tags, through: :spot_search_tags
has_many :spot_search_tags
end
class CafeSearchTag < ApplicationRecord
belongs_to :cafe
belongs_to :search_tag
end
class SpotSearchTag < ApplicationRecord
belongs_to :spot
belongs_to :search_tag
end
class SearchTag < ApplicationRecord
has_many :cafe_search_tags
has_many :spot_search_tags
end
このようにCafeとSpotそれぞれと、SeachTagとの間に中間テーブルを定義してあげないといけません。
さらにこの書き方だと、SearchTagから観たときに、それがSpotにあるのかCafeにあるのかをチェックしなければいけません。 例えばあるタグが付随するCafeとSpotを引っ張りたいときなどは大変です。
そこでポリモーフィック関連を使って、以下のように書くことができました。
class Cafe < ApplicationRecord
has_many :search_tags, through: :destination_search_tags
has_many :destination_search_tags, as: :destinationable
end
class Spot < ApplicationRecord
has_many :search_tags, through: :destination_search_tags
has_many :destination_search_tags, as: :destinationable
end
class DestinationSearchTag < ApplicationRecord
belongs_to :destinationable, polymorphic: true
belongs_to :search_tag
end
class SearchTag < ApplicationRecord
has_many :destination_search_tags
end
参考サイト

Active Record の関連付け - Railsガイド
Active Recordが提供するすべての関連付け機能(アソシエーション)について解説します。

Railsのポリモーフィック関連とはなんなのか - Qiita
はじめに Railsのポリモーフィック(polymorphic、多態性)関連について、実装方法を説明している記事は見かけるのですが、実際これがどんなものでどんな時に便利なのかを説明している記事があまりなく、よくわからないで使っている人もいるようなので本記事を書きました。 ...

Railsのポリモーフィック関連 初心者→中級者へのSTEP10/25 - Qiita
Railsのポリモーフィック関連 はじめに 今回はポリモーフィック関連についてです。 はて、ポリモーフィックとは?の方ように、ポリモーフィックについて簡単に説明して、実際に実装してみたいと思います。 ポリモーフィズムとは## Polymorphism、意味は多様性。オブ...
ja.wikipedia.org/wiki/%E3%83%80%E3%83%83%E3%82%AF%E3%83%B…

オブジェクト指向の3大要素 まとめ - Qiita
「オブジェクト指向の三大要素」について再復習の機会があったのでまとめてみた。 オブジェクト指向の三大要素とは オブジェクト指向言語がもつ代表的な3つの特徴のことで、「カプセル化、継承、ポリモーフィズム」の3つ。 ※ ただ3つの代表的な要素なだけで、これがあるからイコール「...
記事の更新をメールで受け取る
質問・リクエストを送る
記事についての質問や、取り上げてほしいテーマがあればお気軽にどうぞ。いただいた質問はブログ記事として回答し、Q&Aページで公開することがあります。