1

我有一个 Rails 3.2 应用程序,其 Article 模型具有日期字段。我想创建一个范围来检索上个月的所有记录。我遇到的问题是我当前的范围不包括当月的第一天。

# article.rb
scope :last_month, lambda { { conditions: { date: last_month_range } } }

private
def self.last_month_range
  1.month.ago.beginning_of_month..1.month.ago.end_of_month
end

当我运行它时,它会这样做:

SELECT * FROM 'articles' WHERE ('articles`.'date' BETWEEN '2013-07-01 07:00' AND '2013-08-01 06:59:59')

当我查看实际结果时,它仅从日期为 07-02-2013 的文章开始。

但是,如果我将代码更改为:

def self.last_month_range
  (1.month.ago.beginning_of_month - 1.day)..1.month.ago.end_of_month
end

它这样做:

SELECT * FROM 'articles' WHERE ('articles`.'date' BETWEEN '2013-06-30 07:00' AND '2013-08-01 06:59:59')

在这种情况下,它会提取日期为 2013 年 6 月 31 日的文章。

有人可以推荐一个修复吗?谢谢!

4

2 回答 2

3

除非您另有指定,否则 ActiveRecord 会自动转换为 UTC。您需要将范围转换为 UTC。

def self.last_month_range
  1.month.ago.utc.beginning_of_month..1.month.ago.utc.end_of_month
end
于 2013-08-02T03:19:36.793 回答
2

我在接受的答案中遇到了一个错误:

Time.now.utc # => 2015-05-01 01:18:57 UTC

1.month.ago.utc.beginning_of_month #=> 2015-03-01 00:00:00 UTC

问题是在减去月份后时间被转换为UTC。

这是一个正确的解决方案:

def self.last_month_range
  Time.now.utc.prev_month.beginning_of_month..Time.now.utc.prev_month.end_of_month
end
于 2015-05-01T01:22:54.187 回答