title: Combining polymorphic Mongoid model scopes in the base class?
body: <p>I have a simple bit of polymorphism where each subclass has a <code>dead</code> scope, each implemented slightly differently.  I would like to be able to gather them all together from a <code>dead</code> class method from the base class:</p>
  
  <pre><code>class Animal
    include Mongoid::Document
    field :birthday, type: DateTime
  
    def self.dead
      descendants.map(&amp;:dead)
    end
  end
  
  class Dog &lt; Animal
    scope :dead, -&gt;{ where(birthday: { :$lt =&gt; Time.now - 13.years }) }
  end
  
  class GuineaPig &lt; Animal
    scope :dead, -&gt;{ where(birthday: { :$lt =&gt; Time.now - 4.years }) }
  end
  
  class Turtle &lt; Animal
    scope :dead, -&gt;{ where(birthday: { :$lt =&gt; Time.now - 50.years }) }
  end
  </code></pre>
  
  <p>As defined, the <code>Animal::dead</code> method returns an array with each descendant model's scope criteria:</p>
  
  <pre><code>&gt;&gt; Animal.dead
  =&gt; [#&lt;Mongoid::Criteria
    selector: {"birthday"=&gt;{:$lt=&gt;2000-08-23 14:39:24 UTC}}
    options:  {}
    class:    Dog
    embedded: false&gt;
  , #&lt;Mongoid::Criteria
    selector: {"birthday"=&gt;{:$lt=&gt;2009-08-23 14:39:24 UTC}}
    options:  {}
    class:    GuineaPig
    embedded: false&gt;
  , #&lt;Mongoid::Criteria
    selector: {"birthday"=&gt;{:$lt=&gt;1963-08-23 14:39:24 UTC}}
    options:  {}
    class:    Turtle
    embedded: false&gt;
  ]
  </code></pre>
  
  <p>If I want to count up all my dead animals, I have to do something like this:</p>
  
  <pre><code>Animal.dead.map(&amp;:count).reduce(:+)
  </code></pre>
  
  <p>What I would much prefer is if my <code>Animal::dead</code> method returned a regular <code>Mongoid::Criteria</code> of the combined scopes (ORed together) of each descendant's <code>dead</code> criteria, so I could simply do</p>
  
  <pre><code>Animal.dead.count
  </code></pre>
  
  <p>Any ideas for how this could be implemented?</p>
  
  <p>If I were using DataMapper, it has a <a href="http://datamapper.org/docs/find.html" rel="nofollow">nice feature</a> where you can combine/"OR" scopes together using <code>+</code> or <code>|</code> (union operator).  I wasn't able to determine if Mongoid has such a feature, but if it does I think that would solve my issue.</p>
  
  <p>Here's a quick RSpec spec of what I'm after:</p>
  
  <pre><code>describe Animal.dead do
    it { should respond_to(:count, :all, :first, :destroy) }
  end
  
  describe Animal do
    before do
      Animal.all.destroy
      # create 1 dead dog, 2 dead guinea pigs, 3 dead turtles (total 6)
      1.times{ Dog.create(birthday: Time.now - 20.years) }
      2.times{ GuineaPig.create(birthday: Time.now - 5.years) }
      3.times{ Turtle.create(birthday: Time.now - 100.years) }
      # create 3 alive dogs
      3.times{ Dog.create(birthday: Time.now - 6.years) }
    end
  
    it 'should combine descendant animal dead scopes' do
      expect(Animal.dead.count).to eq(6)
    end
  end
  </code></pre>
  
  <p>I'm using Rails so you can assume I have ActiveSupport and all the other helpers available.</p>