Reputation:
I have a table where new records are added daily. How would I go about finding records created in the previous month?
Upvotes: 11
Views: 8638
Reputation: 1
You can use this:
last_month = Time.zone.today.last_month # considering time zones
Thing.where(created_at: last_month.all_month)
Upvotes: 0
Reputation: 1795
Try this for Rails 4+, note that Date.current
will use your application's timezone (specified in application.rb):
scope :created_last_month, lambda {
where(created_at: Date.current.last_month.beginning_of_month..Date.current.last_month.end_of_month)
}
Upvotes: 1
Reputation: 45943
The accepted answer and lambda improvement do not work in Rails 4.
Update for Rails 4:
scope :last_month, -> {
where( 'created_at > ? AND created_at < ?',
Date.today.last_month.beginning_of_month,
Date.today.beginning_of_month )}
Upvotes: 5
Reputation: 16513
In one of my projects i used this way:
Thing.where('created_at BETWEEN ? AND ? ', DateTime.now.beginning_of_month - 1.month, DateTime.now.beginning_of_month)
in Rails 3 using last_month throws an error: Date.today.last_month.beginning_of_month
NoMethodError: undefined method `last_month'
Upvotes: 1
Reputation: 231
this is a good candidate for SQL's BETWEEN syntax
named_scope :last_month, :conditions => ['created_at BETWEEN ? AND ?', Date.today.last_month.beginning_of_month, Date.today.beginning_of_month])
Upvotes: 0
Reputation: 10866
The named_scope
is a rather elegant way to go, I think, but if you take that route you will want to use it with a lambda
method so that the time doesn't get scoped to when the application is initially loaded.
For example, this:
named_scope :last_month, :conditions =>
['created_at > ? AND created_at < ?',
Date.today.last_month.beginning_of_month, Date.today.beginning_of_month]
will work properly the first month your application is up, but improperly the next month, unless the app gets restarted.
But this:
named_scope :last_month, lambda {
{:conditions => ['created_at > ? AND created_at < ?',
Date.today.last_month.beginning_of_month, Date.today.beginning_of_month]}}
will work every time, because the lambda method gets executed on every call, reevaluating the Date.today
s.
Upvotes: 11
Reputation:
Thanks everyone, I ended up going with this:
find(:all, :conditions => ['created_at > ? AND created_at < ?', Date.today.last_month.beginning_of_month, Date.today.beginning_of_month])
Upvotes: 1
Reputation: 54593
Thing.find(:all, :conditions => ["created_at > ?", 1.month.ago.at_beginning_of_month])
Upvotes: 0
Reputation: 19239
Set up a named scope:
named_scope :in_last_month, :conditions => [ "records.created_at > ?", 1.month.ago ]
To call it (in your controller):
Record.in_last_month
Upvotes: 11
Reputation: 237010
Assuming your records are timestamped, you can just do something like this:
Thing.find(:all, :conditions => ["created_at > ?", Time.now - 1.month])
If they're not timestamped, you should start storing the information since it's something you'll want to look up later.
Upvotes: 3