Ruby 去年查询的范围';s数据

Ruby 去年查询的范围';s数据,ruby,ruby-on-rails-3,activerecord,Ruby,Ruby On Rails 3,Activerecord,我已经编写了一个范围,它返回所有具有从本年年初到本年年底的传输日期的对象 scope :year, lambda { where("transfer_date BETWEEN ? AND ?", Time.zone.now.beginning_of_year, Time.zone.now.end_of_year) } 这很好地工作,并为我提供了所需的对象。但现在我想写一个范围,做同样的事情,但为前一年。我知道时间类中没有方法用于去年的开始,所以我认为最好定义一个类方法而不是范围 如果我想返回所

我已经编写了一个范围,它返回所有具有从本年年初到本年年底的传输日期的对象

scope :year, lambda { where("transfer_date BETWEEN ? AND ?", Time.zone.now.beginning_of_year, Time.zone.now.end_of_year) }
这很好地工作,并为我提供了所需的对象。但现在我想写一个范围,做同样的事情,但为前一年。我知道时间类中没有方法用于去年的开始,所以我认为最好定义一个类方法而不是范围

如果我想返回所有日期介于去年年初和去年年底之间的对象,那么用Ruby来表达这一点的最佳方式是什么

我将此作为一个范围编写,但我认为它可以更干净:

scope :previous_year, lambda {where("transfer_date BETWEEN ? AND ?", Time.zone.now.beginning_of_year - 1.year, Time.zone.now.end_of_year - 1.year)}
这个怎么样:

(Time.zone.now - 1.year).beginning_of_year
(Time.zone.now - 1.year).end_of_year

这里有一些优化

既然您已经加载了ActiveSupport并且正在使用它,请使用
ago
方法,编写一些更灵活的东西。您还可以使用一个范围,ActiveRecord可以为您的数据库编写适当的查询,无需字符串替换

scope :from_year, ->(date) { where(transfer_date: date.beginning_of_year..date.end_of_year) }

# usage
Record.from_year(1.year.ago)
这就不那么僵硬了。您现在可以轻松地查询5年前的记录,而无需编写任何新代码。如果你发现自己去年在很多地方都使用过,那就让它成为一种方便的方法:

def self.last_year
  from_year 1.year.ago
end

我使用这行代码

scope:last_year,lambda{where(转让日期:1.year.ago.all_year)}


顺便说一句,你可以简单地使用
1.year.ago
,而不是所有这些
Time.now-1.year
。明白了,但我需要从1月1日到12月31日获取去年的数据。1.year.ago表示今天的日期减去1年。你能详细说明一下我如何清理这个范围吗?我想我可以用1年前的开始和1年前的结束。这似乎比Time.zone.now.Start\u of \u year-1.5年要干净一点。想法?是的,那会更好。请看下面我的答案。这是可行的,我用我编写的一个示例范围更新了我的问题,这个示例范围可以做到这一点,并且可以工作<代码>作用域:前一年,lambda{where(“transfer_date BETWEEN?AND?”,Time.zone.now.start_of_year-1.year,Time.zone.now.end_of_year-1.year)}定义类方法还是坚持作用域更好?谢谢,这更简洁,允许我更灵活地使用。我感谢你的帮助!如果你想做一个月,你可以使用1.month.ago.all\u month
irb(main):032:0> 1.year.ago.all_year
=> Thu, 01 Jan 2015 00:00:00 UTC +00:00..Thu, 31 Dec 2015 23:59:59 UTC +00:00