Inheritance

Mongoid supports inheritance of documents and embedded documents. Consider the following domain model:
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
In the above example, Canvas, Browser and Firefox will all save in the canvases collection. An additional attribute _type is stored in order to make sure when loaded from the database the correct document is returned. This also holds true for the embedded documents Circle, Rectangle, and Shape. Fields and validations are inherited down the hierachy, but not up. A subclass will contain all of its parent's fields and validations, but not vise-versa.

Querying for Subclasses
Querying for subclasses is handled in the normal manner, and although the documents are all in the same collection, queries will only return documents of the correct type, similar to Single Table Inheritance in ActiveRecord.
Canvas.where(:name => "Paper") # Returns Canvas documents and subclasses
Firefox.where(:name => "Window 1") # Returns only Firefox documents

Associations
You can add any type of subclass to a has one or has many association, through either normal setting or through the build and create methods on the association:
firefox = Firefox.new
firefox.shapes.build({ :x => 0, :y => 0 }) # Builds a Shape object
firefox.shapes.build({ :x => 0, :y => 0 }, Circle) # Builds a Circle object
firefox.shapes.create({ :x => 0, :y => 0 }, Rectangle) # Creates a Rectangle object

rect = Rectangle.new(:width => 100, :height => 200)
firefox.shapes

Fork me on GitHub!