Rails3 対応 MongoDB ORM、Mongoid 詳解―継承
Mongoid はドキュメントとエンベッドされたドキュメントの継承をサポートしています。以下のドメインモデルを考えてみます。
class Canvas include Mongoid::Document field :name embeds_many :shapes def render shapes.each { |shape| shape.render } end end class Browser < Canvas field :version, :type => Integer end class Firefox < Browser field :useragent end class Shape include Mongoid::Document field :x, :type => Integer field :y, :type => Integer embedded_in :canvas, :inverse_of => :shapes def render #... end end class Circle < Shape field :radius, :type => Float end class Rectangle < Shape field :width, :type => Float field :height, :type => Float end
上記の例で、Canvas、Browser、Firefox は全て canvases コレクションの中に保存されます。データベースから正しいドキュメントが帰ってくるように、追加のアトリビュート _type が保存されます。また、これは、Circle、Rectangle、Shape といった、エンベッドされたドキュメントにも適用されます。フィールドとバリデーションも子に継承されますが、親には適用されません。子クラスは親クラスの全てのフィールドとバリデーションを含みますが、逆はありません。
子クラスへのクエリ
子クラスへのクエリは通常のクエリと変わりません。ドキュメントはすべて同じコレクションですが、クエリは、正しい型のドキュメントのみ返します。
Canvas.where(:name => "Paper") # Canvas ドキュメントと子クラスを返します Firefox.where(:name => "Window 1") # Firefox ドキュメントだけ返します
関連
通常の代入を通してか、関連の build や create メソッドを通して、has_one または has_many 関連の、どの型の子クラスも追加できます:
firefox = Firefox.new firefox.shapes.build({ :x => 0, :y => 0 }) # Shape オブジェクトを作成します firefox.shapes.build({ :x => 0, :y => 0 }, Circle) # Circle オブジェクトを作成します firefox.shapes.create({ :x => 0, :y => 0 }, Rectangle) # Rectangle オブジェクトを作成します rect = Rectangle.new(:width => 100, :height => 200) firefox.shapes
継承は以上です。