我有很多具有created_at
属性的用户对象,例如
我使用@users = User.all
我希望通过
创建具有不同年龄的User对象的数量@users.size
这些日期范围:
yesterday
last week
last month
last year.
我该怎么做?
我使用mongoid。
答案 0 :(得分:2)
您可以为此编写范围:
class User
include Mongoid::Document
...
## Scopes for calculating relative users
scope :created_yesterday, lambda { where(:created_at.gte => (Time.now - 1.day)) }
scope :created_last_week, lambda { where(:created_at.gte => (Time.now - 1.week)) }
scope :created_last_month, lambda { where(:created_at.gte => (Time.now - 1.month)) }
scope :created_last_year, lambda { where(:created_at.gte => (Time.now - 1.year)) }
...
end
我们需要在这里使用lambda的原因是它将Time.now参数的评估延迟到实际调用范围的时间。如果没有lambda,查询逻辑中使用的时间将是首次评估类的时间,而不是范围本身。
现在我们可以通过简单地调用来获取计数:
User.created_yesterday.count
User.created_last_week.count
...
如果你想要对象:
@users_created_yesterday = User.created_yesterday
您可以在视图中使用@users_created_yesterday
。
<强>更新强>
与昨天一样,如果你的意思是从昨天开始的0:00到昨天结束的23:59之间的时间,你将需要考虑时区。
例如,在你的application.rb中,如果你写了:
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
config.time_zone = 'Central Time (US & Canada)'
如果您使用此功能,则activerecord查询提取的所有时间都将转换为此时区(中部时间(美国和加拿大))。在数据库中,所有时间都将以UTC格式存储,并在从数据库中提取时转换为时区。如果您已注释掉此行,则默认为UTC。您可以使用rake任务rake time:zones:all
获取所有时区,也可以使用rake time:zones:us
仅使用美国时区。
如果您想要application.rb
中指定的时区,则需要在以下代码中使用Time.zone.now
。如果您在以下代码中使用Time.now
,则将根据服务器计算机的时区获取时区。
class User
include Mongoid::Document
...
scope :created_between, lambda { |start_time, end_time| where(:created_at => (start_time...end_time)) }
class << self
## Class methods for calculating relative users
def created_yesterday
yesterday = Time.zone.now - 1.day
created_between(yesterday.beginning_of_day, yesterday.end_of_day)
end
def created_last_week
start_time = (Time.zone.now - 1.week).beginning_of_day
end_time = Time.zone.now
created_between(start_time, end_time)
end
def created_last_month
start_time = (Time.zone.now - 1.month).beginning_of_day
end_time = Time.zone.now
created_between(start_time, end_time)
end
def created_last_year
start_time = (Time.zone.now - 1.year).beginning_of_day
end_time = Time.zone.now
created_between(start_time, end_time)
end
end
..
..
end
因此,您可以编写类方法并计算开始时间和结束时间,将其提供给范围created_between
,您可以像User.created_yesterday
一样调用它们,就像我们之前调用的那样。 / p>
致谢: EdgeRails 。由于它是Mongoid,我不得不抬头看Mongoid docs