ruby – 如何结合两种不同的Mongoid标准

我的模型中定义了以下范围:
scope :upcoming,-> { where(:start_time.gt => Time.Now).asc(:start_time) }
scope :in_progress,-> {
   Now = Time.Now
   where(:start_time.lte => Now).where(:end_time.gte => Now).asc(:start_time)
}

我想创建另一个范围,它结合了两个名为current的范围的结果.我试过这样的事情:

scope :current,-> { self.in_progress | self.upcoming }

但这最终只会将它们视为数组并将它们连接起来.这个问题是,当我尝试使用Model.current调用我的作用域时,我收到以下错误消息:

NoMethodError: undefined method `as_conditions' for #<Array:0xaceb008>

这是因为它将Mongoid Criteria对象转换为数组,但我不希望这样.我希望该对象保留为Mongoid Criteria对象.

我真正想要的是in_progress集和即将到来的集合的结合.

有任何想法吗?谢谢.

解决方法

您可以尝试使用Mongoid的查询方法和取消引用标准的选择器来组成您的标准,但我不一定会建议这样做 – 请参阅下面的示例.我建议你制作第三个范围.请记住,这些范围对应于您希望高效的数据库查询,因此可能值得花时间检查和理解生成的结果和基础MongoDB查询.

模型

class Episode
  include Mongoid::Document
  field :name,type: String
  field :start_time,type: Time
  field :end_time,type: Time

  scope :upcoming,-> { where(:start_time.gt => Time.Now).asc(:start_time) }
  scope :in_progress,-> {
     Now = Time.Now
     where(:start_time.lte => Now).where(:end_time.gte => Now).asc(:start_time)
  }
  scope :current,-> { any_of([upcoming.selector,in_progress.selector]) }
  scope :current_simpler,-> { where(:end_time.gte => Time.Now) }
end

测试

require 'test_helper'

class EpisodeTest < ActiveSupport::TestCase
  def setup
    Episode.delete_all
  end

  test "scope composition" do
    #p Episode.in_progress
    #p Episode.upcoming
    #p Episode.current
    #p Episode.current_simpler

    in_progress_name = 'In Progress'
    upcoming_name = 'Upcoming'
    Episode.create(:name => in_progress_name,:start_time => Time.Now,:end_time => 1.hour.from_Now)
    Episode.create(:name => upcoming_name,:start_time => 1.hour.from_Now,:end_time => 2.hours.from_Now)

    assert_equal([in_progress_name],Episode.in_progress.to_a.map(&:name))
    assert_equal([upcoming_name],Episode.upcoming.to_a.map(&:name))
    assert_equal([in_progress_name,upcoming_name],Episode.current.to_a.map(&:name))
    assert_equal([in_progress_name,Episode.current_simpler.to_a.map(&:name))
  end
end

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...