2007年11月04日

条件付きテーブル間リレーションシップ

関連付けるテーブルは同じなのだが、条件によって別のオブジェクトとして関連付けるレコードを決定する方法がないか探してみた。

具体的に言うと、現在、次のようなテーブルがあって、

create table books ( id int(11) not null auto_increment, title varchar(255) default null, comment text )

本のタイトル(簡単のために本の情報をタイトルだけとしている)とコメントが格納できます。ここでコメントの種類が増えて、ネタばれコメントを追加したくなったとする。

一番素朴な方法は、booksテーブルにnetabareカラムを直接追加してcommentカラムと同じ様に持てばいいわけだが、そもそもコメントは本の情報ではないし、ネタばれコメントにいたっては更にそうだ。

そこでコメントを別テーブル化したくなる。

class Book < ActiveRecord::Base has_one :comment has_one :netabare : class Comment < ActiveRecord::Base belongs_to :book : class Netabare < ActiveRecord::Base belongs_to :book :

とかするわけであるが、これだとモデルクラスとテーブルが2つ増える。

コメントとネタばれは、ユーザの用途は違うがDBに持つ情報としてはほぼ同じであるので、commentsテーブルは共通にできないだろうか。

has_one, belongs_toのリファレンスを見ると、その為に使えそうな:conditionsというオプションが存在した。

commentsテーブルは共通とし、comment_typeというカラムを用意し、これが1の場合、通常のcomment、2の場合ネタばれコメントとして進めてみる。まずはマイグレーションの作成だ。現在コメントはbooks.commentに格納されているので、データの移行も考えた頑張ったマイグレーションを作成する必要がある。

  • 新テーブルcommentsの追加
  • books.commentからcommentsにcomment_type=1でデータ移行
  • books.commentカラムの削除
  • commentsテーブルにbook_id,comment_typeの複合インデックス
  • 続く…

    投稿者 iwazawa : 2007年11月04日 20:09 | トラックバック
    コメント
    コメントする









    名前、アドレスを登録しますか?