You can write scopes for this:
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
The reason we need to use a lambda here is that it delays the evaluation of the Time.now argument to when the scope is actually invoked. Without the lambda the time that would be used in the query logic would be the time that the class was first evaluated, not the scope itself.
Now we can get the counts, by simply calling:
User.created_yesterday.count
User.created_last_week.count
...
If you want the objects:
@users_created_yesterday = User.created_yesterday
You can use @users_created_yesterday
in the views.
Update
Well with yesterday, if you mean time between, yesterday beginning of day 0:00 and yesterday end of day 23:59, you will have to take Time zones into consideration.
Fo example, in your application.rb, if you have written:
# 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)'
If you have use this, all the times fetched by activerecord queries will be converted to this time zone, Central Time (US & Canada). In the database, all the times will be stored in UTC and will be converted to the time zone on fetching from the database. If you have commented out this line, default will be UTC. You can get all the time zones using the rake task rake time:zones:all
or only the US timezones using rake time:zones:us
.
If you want the time zone specified in the application.rb
, you need to use Time.zone.now
, in the following code. If you use Time.now
in the following code, you will get the time zone according to the time zone of your server machine.
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
So, you can write class methods and calculate start time and end time, supply it to the scope created_between
, and you will be able to call them like User.created_yesterday
, like we called before.
Credits: EdgeRails. Since it is Mongoid, I had to look up at Mongoid docs