Hatena::ブログ(Diary)

篳篥日記 このページをアンテナに追加 RSSフィード

2010-06-20

[] 実用ポリモーフィック関連(事例集) 15:22  実用ポリモーフィック関連(事例集)のブックマークコメント

今回はポリモーフィック関連を用いた事例を紹介します。

前回: 実用ポリモーフィック関連(基礎編) - 篳篥日記


事例タイプ1「異なる親モデルで、子モデルを集約する」「異なる親モデルを持てる」


事例1-1「画像モデルを作成して、画像を一元管理する」

前回の説明の例であったような事例です。このブログでも過去に説明しているので、それを参照してみてください。

file_columnを使った画像のアップロード (少し実用的) - 篳篥日記


事例1-2「なんでも入れられるブックマーク(またはお気に入り、クリップボード)の作成」

例えば、提供しているSNSなどのサービス内で、お気に入りのユーザや日記記事、画像、コミュニティなどを、利用者が何でもブックマーク(またはお気に入り登録)できるようにします。

各モデル(ユーザ、日記記事、画像、コミュニティ、etc.)は別々ですが、ポリモーフィック関連を使えば「ブックマーク(またはお気に入り)」という関連で、一つのテーブルに入れる事ができます。

何にでもコメントをつけられるとかでも良いですね。


事例1-3「決済・売上情報の集約」

これはつい最近、モバゲーのゲームアプリ実装で使ってみた事例です。

ゲーム内アイテムとして課金アイテムがあるとします。

売るものがこれだけであれば別にポリモーフィック関連をつかう必要はないのですが、新たにゲーム内の通常アイテム以外に、ユーザのアバター用アイテムを売る事になったとします(もしかしたら、この先、また別のものを売る事になるかもしれません)。

ゲーム内通常アイテムと、アバターアイテムはモデルは異なるのですが、何がどれだけ売れたかというのは一元管理して把握しておきたいという場合に、ポリモーフィック関連が使えます。

売り物の種類はたくさんあるけど、売上はひとつのテーブルを見れば分かるようにできます。

# 通常アイテム
class Item < ActiveRecord::Base
  has_many :purchase_histories, :as => :parent
  has_many :purchase_stats, :as => :parent
end

# アバターアイテム
class AvatarItem < ActiveRecord::Base
  has_many :purchase_histories, :as => :parent
  has_many :purchase_stats, :as => :parent
end

# 購入履歴
class PurchaseHistory < ActiveRecord::Base
  belongs_to :parent, :polymorphic => true
end

# 購入状況(何がどれだけ売れたかの統計)
class PurchaseStat < ActiveRecord::Base
  belongs_to :parent, :polymorphic => true
end

事例1-4「モデルへのタグ付け」

モデルにタグ付けしてタグクラウドを表示する、ということはよくあります。

任意のモデルにタグ付けできるようにするため、ポリモーフィック関連を使います。

Railsプラグインとして有名な、acts_as_taggable (とその派生プラグイン)は、まさにポリモーフィック関連を利用しています。


acts_as_taggableでは、has_many :through を用いて、タグ付け対象のモデルと、実際に付けられるタグ(Tagモデル)が結びつけられています。

この has_many :through の中間にある関連テーブル(Taggingモデル)が、実はポリモーフィックになっており、これにより任意のモデルに対してタグ付けができる設計になっています。

f:id:hichiriki:20100619172955p:image

# タグ付けされるモデル
class Entry < ActiveRecord::Base
  has_many :taggings, :as => :taggable
  has_many :tags, :through => :taggings
end

# 関連テーブル(polymorphic)
class Tagging < ActiveRecord::Base
  belongs_to :taggable, :polymorphic => true
  belongs_to :tag
end

# タグ(関連テーブルの先)
class Tag < ActiveRecord::Base
  has_many :taggings
end

事例タイプ2「親が切り替わる」

ポリモーフィック関連では、子モデルが複数の親モデルを持つ事ができることから、親モデルの切り替えが可能です。


事例2-1「アイテムの付け替え」

これもモバゲーのゲームアプリで利用してみた例です。

以下のようなものを想定します。

  • ユーザは複数のアイテムを持つ
  • アイテムを自分のマシンに付けられる

アイテムが紐付いているモデルが、ユーザとマシン間で切り替わります。

f:id:hichiriki:20100620145539p:image

# ユーザ
class User < ActiveRecord::Base
  has_many :items, :as => :parent
end

# マシン
class Machine < ActiveRecord::Base
  has_many :items, :as => :parent
end

# アイテム
class Item < ActiveRecord::Base
  belongs_to :parent, :polymorphic => true
end


# 使用例
user = User.new
machine = Machine.new
item = Item.new
user.items << item # アイテムはユーザが持っている(親はユーザ)
machine.items << item # アイテムをマシンに付けた(親はマシン)

今回は、ポリモーフィック関連を用いた事例を紹介しました。

これでどのような事にポリモーフィック関連を用いるか、大体分かったのではないでしょうか。