Reputation: 3337
I've written a scope that returns all objects with a transfer_date from the beginning of the current year to the end of the current year.
scope :year, lambda { where("transfer_date BETWEEN ? AND ?", Time.zone.now.beginning_of_year, Time.zone.now.end_of_year) }
This works well and gives me the objects that I need. But now I'm looking to write a scope that does the same thing but for the previous year. I know there's no method in the Time class for beginning_of_last_year so I'm thinking that it might be better to define a class method instead of a scope.
If I wanted to return all objects with a date between the beginning of last year and the end of last year, what would be the best way to express this in Ruby?
I've written this as a scope but I think it can be cleaner:
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)}
Upvotes: 2
Views: 2000
Reputation: 80041
There are a few optimizations I'd make here.
Since you already have ActiveSupport loaded and you're using it, make use of the ago
method, and write something that's a little more flexible. You can also use a range and ActiveRecord can handle writing the appropriate query for your DB, no string substitution needed.
scope :from_year, ->(date) { where(transfer_date: date.beginning_of_year..date.end_of_year) }
# usage
Record.from_year(1.year.ago)
This is a lot less rigid. You can now easily query for records that are from 5 years ago without writing any new code. If you find yourself using last year in a lot of places, make it a convenience method:
def self.last_year
from_year 1.year.ago
end
Upvotes: 4
Reputation: 228
I use this line of code
scope :last_year, lambda {where(transfer_date: 1.year.ago.all_year)}
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
Upvotes: 0
Reputation: 3754
How about this:
(Time.zone.now - 1.year).beginning_of_year
(Time.zone.now - 1.year).end_of_year
Upvotes: 2