ruby - Combining polymorphic Mongoid model scopes in the base class? -


i have simple bit of polymorphism each subclass has dead scope, each implemented differently. able gather them dead class method base class:

class animal   include mongoid::document   field :birthday, type: datetime    def self.dead     descendants.map(&:dead)   end end  class dog < animal   scope :dead, ->{ where(birthday: { :$lt => time.now - 13.years }) } end  class guineapig < animal   scope :dead, ->{ where(birthday: { :$lt => time.now - 4.years }) } end  class turtle < animal   scope :dead, ->{ where(birthday: { :$lt => time.now - 50.years }) } end 

as defined, animal::dead method returns array each descendant model's scope criteria:

>> animal.dead => [#<mongoid::criteria   selector: {"birthday"=>{:$lt=>2000-08-23 14:39:24 utc}}   options:  {}   class:    dog   embedded: false> , #<mongoid::criteria   selector: {"birthday"=>{:$lt=>2009-08-23 14:39:24 utc}}   options:  {}   class:    guineapig   embedded: false> , #<mongoid::criteria   selector: {"birthday"=>{:$lt=>1963-08-23 14:39:24 utc}}   options:  {}   class:    turtle   embedded: false> ] 

if want count dead animals, have this:

animal.dead.map(&:count).reduce(:+) 

what prefer if animal::dead method returned regular mongoid::criteria of combined scopes (ored together) of each descendant's dead criteria, do

animal.dead.count 

any ideas how implemented?

if using datamapper, has nice feature can combine/"or" scopes using + or | (union operator). wasn't able determine if mongoid has such feature, if think solve issue.

here's quick rspec spec of i'm after:

describe animal.dead   { should respond_to(:count, :all, :first, :destroy) } end  describe animal   before     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    'should combine descendant animal dead scopes'     expect(animal.dead.count).to eq(6)   end end 

i'm using rails can assume have activesupport , other helpers available.

i have temporary solution seems work:

class animal   include mongoid::document   field :birthday, type: datetime    def self.dead     self.or(*descendants.map{|d| d.dead.type(d).selector})   end end 

however, seems hackish. leave question open while in case has cleaner suggestions.


Comments

Popular posts from this blog

java - Run a .jar on Heroku -

java - Jtable duplicate Rows -

validation - How to pass paramaters like unix into windows batch file -