从Rails数据库中选择具有特定年份和月份的条目

时间:2015-02-21 06:15:19

标签: ruby-on-rails activerecord

如何在日期时间内选择具有给定日期和月份的所有数据库条目?我试过这个:

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)
}

我如何以数据库无关的方式执行此操作?

1 个答案:

答案 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:002015-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'