Last active
December 26, 2015 14:18
-
-
Save leods92/7164159 to your computer and use it in GitHub Desktop.
Adds time zone aware data grouping method to ActiveRecord.
If you want to group a large set of database rows by date using a timestamp
as reference, the optimal way is to do it right in the database.
When doing it though there are some issues with time zones that #group_date solves. For example, if a UTC timestamp is set to 2013-12-01 01:00 and …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ActiveRecord | |
module Querying | |
delegate :group_date, :to => :scoped | |
end | |
module QueryMethods | |
def group_date(column_name = nil) | |
return self if column_name.blank? | |
# Rails uses a non standard time zone naming. | |
# Let's get tz database standard which is used by many databases. | |
# Using this instead of time offset or other approaches is necessary | |
# in order to deal with daylight saving time automatically. | |
zone = Time.zone.tzinfo.name | |
# Rails stores timestamps without time zones by default. | |
# So we must first set a zone to column_name (column_name at time zone 'UTC'). | |
# Note that even though Rails does that under the hood when you use ActiveRecord, | |
# that's not applicable here. | |
# Then, we set column to application's time zone so that the database can | |
# convert timestamp to proper date. | |
convert = "at time zone 'UTC' at time zone '#{zone}'" | |
date = "date(#{table.name}.#{column_name} #{convert})" | |
# Since converting date is not that straight-forward, | |
# this will automatically return converted date. | |
# We gotta convert output date to assure Rails won't convert it again. | |
clone.group(date).select("#{date} #{convert} as #{column_name}") | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment