如何在日期时间内选择具有给定日期和月份的所有数据库条目?我试过这个:
scope :with_year_and_month, ->(year, month) {
where("YEAR(created_at) = ? AND MONTH(created_at) = ?", month, year)
}
现在,这在MySQL数据库中可以正常工作,但在Sqlite数据库中它会失败,因为Sqlite没有实现MONTH()
和YEAR()
函数。以下在Sqlite中工作正常:
scope :with_year_and_month, ->(year, month) {
where("strftime('%m', created_at) = ? AND strftime('%Y', created_at) = ?", "%02d" % month, year.to_s)
}
我如何以数据库无关的方式执行此操作?
答案 0 :(得分:5)
我认为你应该让活动记录处理这个,因为它检查它使用的数据库并为每个数据库使用驱动程序,诀窍是找到一个通用的查询来运行,对我来说这就是我能做到的想出来,可能不是最好的,但我可以提出建议
scope :with_year_and_month, ->(year, month) {
where(created_at: Date.new(year,month,1)..Date.new(year,month,-1))
}
这将生成一个查询之间的
WHERE created_at BETWEEN '2015-02-01' AND '2015-02-28'
我认为这应该适合你
如果created_at为DateTime
,那么您应该将Date
替换为DateTime
对象,这样就不会错过2015-02-28 00:00:00
和2015-02-28 23:59:59
之间的时间,但是你需要额外的时间参数
scope :with_year_and_month, ->(year, month) {
where(created_at: DateTime.new(year,month,1)..DateTime.new(year,month,-1, -1, -1, -1))
}
当然你可以创建一个小辅助函数来返回那些日期并缩短你的方法 结果将是
Where created_at BETWEEN '2015-02-01 00:00:00' AND '2015-02-28 23:59:59'
<强>更新强>
所以经过几次评论后,这里是最终版本
scope :with_year_and_month, ->(year, month) {
date = DateTime.new(year,month)
where(created_at: date...date.next_month)
}
生成的查询看起来像这样
created_at >= '2015-02-01 00:00:00' AND created_at < '2015-03-01 00:00:00'