2010-06-20
■[Rails] 実用ポリモーフィック関連(事例集) 
今回はポリモーフィック関連を用いた事例を紹介します。
事例タイプ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モデル)が、実はポリモーフィックになっており、これにより任意のモデルに対してタグ付けができる設計になっています。
# タグ付けされるモデル 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「アイテムの付け替え」
以下のようなものを想定します。
- ユーザは複数のアイテムを持つ
- アイテムを自分のマシンに付けられる
アイテムが紐付いているモデルが、ユーザとマシン間で切り替わります。
# ユーザ 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 # アイテムをマシンに付けた(親はマシン)
今回は、ポリモーフィック関連を用いた事例を紹介しました。
これでどのような事にポリモーフィック関連を用いるか、大体分かったのではないでしょうか。
- 5 http://reader.livedoor.com/reader/
- 4 http://antenna.larme.dnsalias.net/
- 3 http://www.google.co.jp/search?hl=&q=rails+入力補完&sourceid=navclient-ff&rlz=1B3GGGL_jaJP343JP343&ie=UTF-8
- 3 http://www.google.co.jp/search?hl=ja&source=hp&q=rails+モーダル&aq=f&aqi=g1&aql=&oq=&gs_rfai=
- 3 http://www.google.co.jp/search?num=50&hl=ja&client=safari&rls=en&q=モバゲー API RAILS&aq=f&aqi=&aql=&oq=&gs_rfai=
- 3 http://www.google.co.jp/search?q=rails+friendship&hl=ja&source=lnt&tbs=lr:lang_1ja&lr=lang_ja&sa=X&ei=zNIeTPCeA8mekQXY8oHOCw&ved=0CAcQpwU
- 2 http://pipes.yahoo.com/pipes/pipe.info?_id=02db597254ec68550537866a2fca2ce6
- 2 http://pipes.yahoo.com/pipes/pipe.info?_id=VPw6npu13RGKo15vBRNMsA
- 2 http://webcache.googleusercontent.com/search?q=cache:HFqlfctltbsJ:d.hatena.ne.jp/hichiriki/20090407/1239116302+rails+javascript+ render+モーダル&cd=1&hl=ja&ct=clnk&gl=jp
- 2 http://webcache.googleusercontent.com/search?q=cache:lLUi6RRo87AJ:d.hatena.ne.jp/hichiriki/20090209+ajax_upload&cd=2&hl=ja&ct=clnk&gl=jp&client=firefox-a












