読者です 読者をやめる 読者になる 読者になる

プログラミング 美徳の不幸

Ruby, Rails, JavaScriptなどのプログラミングまとめ、解説、備忘録。

単一テーブル継承によって作成されたサブクラスをさらに継承する

やりたいこと
GithubのFeedのようなものに、さらにTweetを混入させたTLを作成したい。

<イメージ>
(こっちが新しい)
・(octolion)「この機能を作ったので、取り込んで!」
・octolionさんがにpull requestを送りました
・octodogさんがにstarをつけました
・(octocat) 「こういうレポジトリを作ったよ、みんなフォークしてね!」
・octocatさんがを作成しました
(こっちが古い)


これを@tweets+@newsみたいなことするのはめんどい。だから@feedsで全て取得したい。

◯単一テーブル継承


・Feed
|- Tweet つぶやきの方
|- News システム側で文言が決定されるニュースの方

さらに、Newsはレポジトリを作成したとか、フォークしたとか、いろんな種類があるがこれをtypeで処理するのは「タイプコードからポリモーフィズムへ」の原則に反するので、Newsは抽象クラスとして実際のニュースはそれを継承させたものを使用したい。

・Feed
|- Tweet
|- News
|- RepositoryCreateNews
|- RepositoryForkedNews

単一テーブル継承によって作成されたクラスにサブクラスを作るとどうなるのか、調べてもなかったので実験したところ、FeedのtypeにRepositoryCreateNewsなどがそのまま入るだけで普通に使えた。

で、feedsのテーブルにbodyを持たせてこういうふうに表示したい。

- @feeds.each do |feed|
  = feed.body


こういうときって、newsも全てtableに格納したほうがいいのか、bodyをオーバーライドするなどして動的に吐き出したほうがいいのかどちらなんだろう。実は後者にした場合"(user)が(repository)を作成しました"という文言を出力したいときにrepositoryに対する参照を持たなければいけないので、Tweetと同じテーブルにすることに無理が生じる。

とりあえずどっちがいいのかもう少し考えますが、単一テーブル継承の二重化はテクニックとして使えそうです。