ポリモーフィック関連付けとは
動機
Railsで記事に埋め込み機能を実装する際に、ポリモーフィック関連付けが出てきたので、理解を深めるためにも備忘録としてメモを書いていきます。
以下のモデル構成で説明していきます。
# article_block.rb class ArticleBlock < ApplicationRecord belongs_to :article belongs_to :blockable, polymorphic: true, dependent: :destroy # ... end
# sentence.rb class Sentence < ApplicationRecord has_one :article_block, as: :blockable, dependent: :destroy # ... end
# medium.rb class Medium < ApplicationRecord has_one :article_block, as: :blockable, dependent: :destroy # ... end
# embed.rb class Embed < ApplicationRecord has_one :article_block, as: :blockable, dependent: :destroy # ... end
# article.rb class Article < ApplicationRecord has_many :article_blocks, -> { order(:level) }, inverse_of: :article has_many :sentences, through: :article_blocks, source: :blockable, source_type: 'Sentence' has_many :media, through: :article_blocks, source: :blockable, source_type: 'Medium' has_many :embeds, through: :article_blocks, source: :blockable, source_type: 'Embed' # ... end
ポリモーフィックとはなにか?
ポリモーフィック関連付けを使うと、ある1つのモデルが他の複数のモデルに属していることを、1つの関連付けだけで表現できます。
:引用 Active Record の関連付け - Railsガイド
上記のコードを例にすると、ArticleBlock
モデルは、複数のモデルSentence
, Medium
, Embed
に属していることを1つの関連付けのblockable
だけで表現できています。
ポリモーフィックってなんなの?という人におすすめの記事です。
Railsのポリモーフィック関連とはなんなのか - Qiita
この記事を読んで、「ダックタイピング」、「インターフェース」という言葉がでてきてあまり理解できなかったので、調べようと思いました。
ポリモーフィック関連付けの方法
説明
今回のモデル構成で説明してみます。
- belongs_to宣言に:polymorphicオプションを指定すると、ポリモーフィック関連になる
下記のArticleBlock
クラスでポリモーフィック関連を利用するために、belongs_to :blockable
にpolymorphic
オプションが指定されています。
# article_block.rb class ArticleBlock < ApplicationRecord belongs_to :article belongs_to :blockable, polymorphic: true, dependent: :destroy # ... end
asオプションとは?
:asオプションを設定すると、ポリモーフィック関連付けを指定できます。
:引用 Active Record の関連付け - Railsガイド
ポリモーフィック関連付けの利点
1つのモデルが他の複数のモデルに属していることを、一つの関連付けだけで表現できることです。 両者のコードを比べるとポリモーフィック関連付けありの方がコードが見やすくなっているのがわかると思います。
# article_block.rb # ポリモーフィック関連付けなし class ArticleBlock < ApplicationRecord belongs_to :article belongs_to :sentence belongs_to :medium belongs_to :embed # ... end
# article_block.rb # ポリモーフィック関連付けあり class ArticleBlock < ApplicationRecord belongs_to :article belongs_to :blockable, polymorphic: true, dependent: :destroy # ... end
参考にしたサイト
Active Record の関連付け - Railsガイド
Railsのポリモーフィック関連とはなんなのか - Qiita