Commit 550f3fc2ff9b4e00204682d39412a5975e118691
1 parent
b2363c28
Exists in
master
and in
17 other branches
Added tests
Showing
4 changed files
with
64 additions
and
5 deletions
Show diff stats
README.md
... | ... | @@ -16,13 +16,13 @@ PostgreSQL only at the moment - support for other datastores coming soon |
16 | 16 | |
17 | 17 | ```ruby |
18 | 18 | User.group_by_day(:created_at).count |
19 | -# => {2013-04-16 00:00:00 UTC=>50,2013-04-17 00:00:00 UTC=>100} | |
19 | +# => {"2013-04-16 00:00:00+00" => 50, "2013-04-17 00:00:00+00" => 100} | |
20 | 20 | |
21 | 21 | Task.group_by_month(:updated_at).count |
22 | -# => {2013-04-01 00:00:00 UTC=>23,2013-04-01 00:00:00 UTC=>44} | |
22 | +# => {"2013-03-01 00:00:00+00" => 23, "2013-04-01 00:00:00+00" => 44} | |
23 | 23 | |
24 | 24 | Goal.group_by_year(:accomplished_at).count |
25 | -# => {2012-01-01 00:00:00 UTC=>11,2013-01-01 00:00:00 UTC=>3} | |
25 | +# => {"2012-01-01 00:00:00+00" => 11, "2013-01-01 00:00:00+00" => 3} | |
26 | 26 | ``` |
27 | 27 | |
28 | 28 | The default time zone is `Time.zone`. Pass a time zone as the second argument. |
... | ... | @@ -30,7 +30,7 @@ The default time zone is `Time.zone`. Pass a time zone as the second argument. |
30 | 30 | ```ruby |
31 | 31 | time_zone = ActiveSupport::TimeZone["Pacific Time (US & Canada)"] |
32 | 32 | User.group_by_week(:created_at, time_zone).count |
33 | -# => {2013-04-16 00:00:00 UTC=>80,2013-04-17 00:00:00 UTC=>70} | |
33 | +# => {"2013-04-16 07:00:00+00" => 80, "2013-04-17 07:00:00+00" => 70} | |
34 | 34 | ``` |
35 | 35 | |
36 | 36 | Use it with anything you can use `group` with: |
... | ... | @@ -45,6 +45,8 @@ Go nuts! |
45 | 45 | Request.where(page: "/home").group_by_minute(:started_at).maximum(:request_time) |
46 | 46 | ``` |
47 | 47 | |
48 | +**Note:** On Rails 4 edge, queries return a Time object (much better!) as a result of [this commit](https://github.com/rails/rails/commit/2cc09441c2de57b024b11ba666ba1e72c2b20cfe) | |
49 | + | |
48 | 50 | ## Installation |
49 | 51 | |
50 | 52 | Add this line to your application's Gemfile: | ... | ... |
groupdate.gemspec
lib/groupdate.rb
... | ... | @@ -29,9 +29,10 @@ module Groupdate |
29 | 29 | # http://www.postgresql.org/docs/9.1/static/functions-datetime.html |
30 | 30 | %w(microseconds milliseconds second minute hour day week month quarter year decade century millennium).each do |field| |
31 | 31 | self.scope :"group_by_#{field}", lambda {|column, time_zone = Time.zone| |
32 | - if time_zone.is_a?(ActiveSupport::TimeZone) | |
32 | + if defined?(ActiveSupport::TimeZone) and time_zone.is_a?(ActiveSupport::TimeZone) | |
33 | 33 | time_zone = time_zone.tzinfo.name |
34 | 34 | end |
35 | + time_zone ||= "Etc/UTC" | |
35 | 36 | sql = "DATE_TRUNC('#{field}', #{column}::timestamptz AT TIME ZONE ?) AT TIME ZONE ?" |
36 | 37 | group(sanitize_sql_array([sql, time_zone, time_zone])) |
37 | 38 | } | ... | ... |
... | ... | @@ -0,0 +1,54 @@ |
1 | +require "minitest/autorun" | |
2 | +require "active_record" | |
3 | +require "groupdate" | |
4 | +require "logger" | |
5 | + | |
6 | +# for debugging | |
7 | +# ActiveRecord::Base.logger = Logger.new(STDOUT) | |
8 | + | |
9 | +# rails does this in activerecord/lib/active_record/railtie.rb | |
10 | +ActiveRecord::Base.default_timezone = :utc | |
11 | +ActiveRecord::Base.time_zone_aware_attributes = true | |
12 | + | |
13 | +# start connection | |
14 | +ActiveRecord::Base.establish_connection adapter: "postgresql", database: "groupdate" | |
15 | + | |
16 | +# ActiveRecord::Migration.create_table :users do |t| | |
17 | +# t.string :name | |
18 | +# t.integer :score | |
19 | +# t.timestamps | |
20 | +# end | |
21 | + | |
22 | +class User < ActiveRecord::Base | |
23 | +end | |
24 | + | |
25 | +class TestGroupdate < MiniTest::Unit::TestCase | |
26 | + def setup | |
27 | + User.delete_all | |
28 | + [ | |
29 | + {name: "Andrew", score: 1, created_at: Time.parse("2013-04-01 00:00:00 UTC")}, | |
30 | + {name: "Jordan", score: 2, created_at: Time.parse("2013-04-01 00:00:00 UTC")}, | |
31 | + {name: "Nick", score: 3, created_at: Time.parse("2013-04-02 00:00:00 UTC")} | |
32 | + ].each{|u| User.create!(u) } | |
33 | + end | |
34 | + | |
35 | + def test_count | |
36 | + expected = { | |
37 | + "2013-04-01 00:00:00+00" => 2, | |
38 | + "2013-04-02 00:00:00+00" => 1 | |
39 | + } | |
40 | + assert_equal expected, User.group_by_day(:created_at).count | |
41 | + end | |
42 | + | |
43 | + def test_time_zone | |
44 | + expected = { | |
45 | + "2013-03-31 07:00:00+00" => 2, | |
46 | + "2013-04-01 07:00:00+00" => 1 | |
47 | + } | |
48 | + assert_equal expected, User.group_by_day(:created_at, "America/Los_Angeles").count | |
49 | + end | |
50 | + | |
51 | + def test_where | |
52 | + assert_equal({"2013-04-02 00:00:00+00" => 1}, User.where("score > 2").group_by_day(:created_at).count) | |
53 | + end | |
54 | +end | ... | ... |