Ruby中如何查询start_at满足小于1小时或3小时的Trip对象
解决Trip模型的时间窗口查询问题
你需要的是筛选出仅处于两个特定时间窗口内的Trip对象:
- 窗口1:start_at在最近1小时内(距离当前时间小于1小时)
- 窗口2:start_at在过去2-3小时之间(距离当前时间大于等于2小时且小于等于3小时)
之前的代码逻辑完全错误,Trip.where("start_at < ? ", 1.hour.ago) 会返回所有早于1小时前的Trip,这和你的需求刚好相反。
下面是两种正确的实现方式:
方式1:SQL字符串查询(直观易懂)
Trip.where( "(start_at >= ?) OR (start_at >= ? AND start_at <= ?)", 1.hour.ago, 3.hour.ago, 2.hour.ago )
这里的逻辑是:
- 第一个条件匹配最近1小时内的Trip
- 第二个条件匹配3小时前到2小时前之间的Trip(包含边界值)
方式2:Arel查询(更安全的ActiveRecord写法)
如果想避免直接写SQL字符串,用Arel可以让查询更贴合Rails的ORM风格:
start_at_column = Trip.arel_table[:start_at] time_now = Time.current Trip.where( start_at_column.gteq(time_now - 1.hour).or( start_at_column.between(time_now - 3.hour..time_now - 2.hour) ) )
验证你的例子
- 当当前时间为10:00时,第一个条件匹配9:00-10:00的Trip,9:00的start_at符合条件会被返回
- 当当前时间为12:00时,第二个条件匹配9:00-10:00的Trip,9:00的start_at符合条件会被返回
- 当当前时间为11:00时,9:00的start_at不在任何窗口内,不会被返回
- 当当前时间为13:00时,9:00的start_at早于3小时前,不会被返回
内容的提问来源于stack exchange,提问作者Bahubali Ak
相关产品推荐
相关产品推荐

