Railsで開発していると、polymorphic(ポリモーフィック)関連という言葉を目にすることがあります。
ただ、実際に使ったことがなかったり、なんとなくで理解しているという方も多いのではないでしょうか?
この記事では、そんな方向けに ポリモーフィック関連の仕組みと使い方 を説明します。
ポリモーフィック(polymorphic)とは?
簡単に言うと、1つのモデル(テーブル)が、複数の親モデルと関連付けられる仕組みです。
例)コメント機能
Post(投稿)親モデルPhoto(写真)親モデルComment(コメント)子モデル
投稿と写真にコメントをつけたい!
でも、commentsテーブルを2つ作るのは非効率。
そんなときに使えるのが polymorphic: true です。
実装例
ER図(簡易版)
子テーブルには、関連先のモデル名を示す commentable_type と、関連先レコードのidを示す commentable_id という2つのカラムを用意します。
+---------+ +----------+
| posts | | photos |
+---------+ +----------+
| id |◀─┐ | id |◀─┐
| title | │ | url | │
+---------+ │ +----------+ │
│ │
▼ ▼
+-----------------------------+
| comments |
+-----------------------------+
| id |
| body |
| commentable_type (string) | ← "Post" or "Photo"
| commentable_id (integer) | ← 対象モデルのid
+-----------------------------+
モデル設定
親モデルでは:asオプション付きのhas_manyを、子モデルでは:polymorphicオプション付きのbelongs_toを書きます。
ここでのポイントは、has_many の :as オプションや belongs_to の引数、そして comments テーブル内の commentable_type / commentable_id というカラム名の「commentable」の部分をすべて一致させていることです。
class Post < ApplicationRecord
has_many :comments, as: :commentable
end
class Photo < ApplicationRecord
has_many :comments, as: :commentable
end
class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
end
使い方
post = Post.create(title: "初投稿")
photo = Photo.create(url: "baby.png")
post.comments.create(body: "いいね!")
photo.comments.create(body: "かわいい!")
Comment.all で確認すると、以下のようにどちらのコメントも同じ comments テーブルに保存されます。
| id | body | commentable_type | commentable_id |
|---|---|---|---|
| 1 | “いいね!” | “Post” | 1 |
| 2 | “かわいい!” | “Photo” | 1 |
最後に
ポリモーフィック関連は、少しとっつきにくい名前ですが、使い方はシンプルですね。



コメント