ฉันมีความหลากหลายเล็กน้อยโดยแต่ละคลาสย่อยมีขอบเขต dead
โดยแต่ละคลาสนำไปใช้แตกต่างกันเล็กน้อย ฉันต้องการที่จะรวบรวมพวกมันทั้งหมดเข้าด้วยกันจากเมธอดคลาส dead
จากคลาสพื้นฐาน:
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
ตามที่กำหนดไว้ Animal::dead
วิธีการส่งกลับอาร์เรย์ที่มีเกณฑ์ขอบเขตของรุ่นสืบทอดแต่ละรุ่น:
>> 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>
]
หากฉันต้องการนับจำนวนสัตว์ที่ตายแล้วทั้งหมด ฉันต้องทำดังนี้:
Animal.dead.map(&:count).reduce(:+)
สิ่งที่ฉันต้องการมากคือถ้าวิธีการ Animal::dead
ของฉันส่งคืนขอบเขตปกติ Mongoid::Criteria
ของขอบเขตรวม (ORed ร่วมกัน) ของเกณฑ์ dead
ของผู้สืบทอดแต่ละคน ดังนั้นฉันจึงสามารถทำได้
Animal.dead.count
มีความคิดเห็นเกี่ยวกับวิธีการดำเนินการนี้หรือไม่?
ถ้าฉันใช้ DataMapper มันมีคุณลักษณะที่ดี ที่คุณสามารถรวม/"หรือ" ขอบเขตเข้าด้วยกัน ใช้ +
หรือ |
(ตัวดำเนินการสหภาพ) ฉันไม่สามารถระบุได้ว่า Mongoid มีคุณสมบัติดังกล่าวหรือไม่ แต่ถ้าเป็นเช่นนั้น ฉันคิดว่านั่นจะช่วยแก้ปัญหาของฉันได้
นี่เป็นข้อมูลจำเพาะ RSpec โดยย่อของสิ่งที่ฉันติดตาม:
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
ฉันใช้ Rails เพื่อให้คุณสามารถสันนิษฐานได้ว่าฉันมี ActiveSupport และตัวช่วยอื่นๆ ทั้งหมดที่มีอยู่