I have an ActiveRecord model that has a date attribute. Is it possible to utilize that date attribute to find by Year, Day and Month:
Model.find_by_year(2012)
Model.find_by_month(12)
Model.find_by_day(1)
or is it simply possible to find_by_date(2012-12-1).
I was hoping I could avoid creating Year, Month and Day attributes.
Assuming that your “date attribute” is a date (rather than a full timestamp) then a simple
wherewill give you your “find by date”:You don’t want
find_by_date_columnas that will give at most one result.For the year, month, and day queries you’d want to use the
extractSQL function:However, if you’re using SQLite, you’d have to mess around with
strftimesince it doesn’t know whatextractis:The
%mand%dformat specifiers will add leading zeroes in some case and that can confuse the equality tests, hence thecast(... as int)to force the formatted strings to numbers.ActiveRecord won’t protect you from all the differences between databases so as soon as you do anything non-trivial, you either have to build your own portability layer (ugly but sometimes necessary), tie yourself to a limited set of databases (realistic unless you’re releasing something that has to run on any database), or do all your logic in Ruby (insane for any non-trivial amount of data).
The year, month, and day-of-month queries will be pretty slow on large tables. Some databases let you add indexes on function results but ActiveRecord is too stupid to understand them so it will make a big mess if you try to use them; so, if you find that these queries are too slow then you’ll have to add the three extra columns that you’re trying to avoid.
If you’re going to be using these queries a lot then you could add scopes for them but the recommended way to add a scope with an argument is just to add a class method:
So you’d have class methods that look like this: