groupdate 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/README.md +6 -10
- data/lib/groupdate.rb +4 -160
- data/lib/groupdate/order_hack.rb +11 -0
- data/lib/groupdate/scopes.rb +101 -0
- data/lib/groupdate/series.rb +89 -0
- data/lib/groupdate/version.rb +1 -1
- data/test/groupdate_test.rb +21 -8
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20e5986d43228afba669a7b5928f555a302680bc
|
4
|
+
data.tar.gz: e0190e033c4fa7a3b51eefa09254a61f44d55337
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 059e84d54ea52420c4d2fa12ae479623652b704b03246c937f249548b9f55db8ca1e3a469404350b62c8b127d9276cefdc22f2f463d62fcdb35aec6de90baaa8
|
7
|
+
data.tar.gz: 5d61f760f0cc7a01d83df61b11b687c20761fd345e8e6152ae4b7f1955d57d54ba6a2e03ec759364ab12da0baf94007b99a8db1990be3708a04e82ad2e89a22f
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -123,7 +123,7 @@ Awesome, but you want to see the first week of May. Pass a range as the third a
|
|
123
123
|
# pretend today is May 7
|
124
124
|
time_range = 6.days.ago..Time.now
|
125
125
|
|
126
|
-
User.group_by_day(:created_at, Time.zone, time_range).count
|
126
|
+
User.group_by_day(:created_at, Time.zone, time_range).count
|
127
127
|
# {
|
128
128
|
# 2013-05-01 00:00:00 UTC => 0,
|
129
129
|
# 2013-05-02 00:00:00 UTC => 1,
|
@@ -133,16 +133,8 @@ User.group_by_day(:created_at, Time.zone, time_range).count(:created_at)
|
|
133
133
|
# 2013-05-06 00:00:00 UTC => 0,
|
134
134
|
# 2013-05-07 00:00:00 UTC => 0
|
135
135
|
# }
|
136
|
-
```
|
137
|
-
|
138
|
-
Wow, SQL magic!
|
139
|
-
|
140
|
-
**Note:** Be sure to pass the column name to `count`. Otherwise, you get `1` for empty groups.
|
141
|
-
|
142
|
-
For the day of the week and hour of the day, just pass `true`.
|
143
136
|
|
144
|
-
|
145
|
-
User.group_by_day_of_week(:created_at, Time.zone, true).count(:created_at)
|
137
|
+
User.group_by_day_of_week(:created_at, Time.zone, time_range).count
|
146
138
|
# {
|
147
139
|
# 0 => 0,
|
148
140
|
# 1 => 1,
|
@@ -154,6 +146,10 @@ User.group_by_day_of_week(:created_at, Time.zone, true).count(:created_at)
|
|
154
146
|
# }
|
155
147
|
```
|
156
148
|
|
149
|
+
Results are returned in ascending order, so no need to sort.
|
150
|
+
|
151
|
+
Also, this form of the method returns a Groupdate::Series instead of an ActiveRecord::Relation. ActiveRecord::Relation method calls (like `where` and `joins`) should come before this.
|
152
|
+
|
157
153
|
## Installation
|
158
154
|
|
159
155
|
Add this line to your application's Gemfile:
|
data/lib/groupdate.rb
CHANGED
@@ -1,171 +1,15 @@
|
|
1
1
|
require "groupdate/version"
|
2
|
-
require "
|
2
|
+
require "groupdate/scopes"
|
3
3
|
|
4
|
-
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
# Pattern from kaminari
|
8
|
-
# https://github.com/amatsuda/kaminari/blob/master/lib/kaminari/models/active_record_extension.rb
|
9
|
-
included do
|
10
|
-
# Future subclasses will pick up the model extension
|
11
|
-
class << self
|
12
|
-
def inherited_with_groupdate(kls) #:nodoc:
|
13
|
-
inherited_without_groupdate kls
|
14
|
-
kls.send(:include, ClassMethods) if kls.superclass == ActiveRecord::Base
|
15
|
-
end
|
16
|
-
alias_method_chain :inherited, :groupdate
|
17
|
-
end
|
18
|
-
|
19
|
-
# Existing subclasses pick up the model extension as well
|
20
|
-
self.descendants.each do |kls|
|
21
|
-
kls.send(:include, ClassMethods) if kls.superclass == ActiveRecord::Base
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
module ClassMethods
|
26
|
-
extend ActiveSupport::Concern
|
27
|
-
|
28
|
-
included do
|
29
|
-
# Field list from
|
30
|
-
# http://www.postgresql.org/docs/9.1/static/functions-datetime.html
|
31
|
-
time_fields = %w(second minute hour day week month year)
|
32
|
-
number_fields = %w(day_of_week hour_of_day)
|
33
|
-
(time_fields + number_fields).each do |field|
|
34
|
-
self.scope :"group_by_#{field}", lambda {|*args|
|
35
|
-
column = connection.quote_table_name(args[0])
|
36
|
-
time_zone = args[1] || Time.zone || "Etc/UTC"
|
37
|
-
if time_zone.is_a?(ActiveSupport::TimeZone) or time_zone = ActiveSupport::TimeZone[time_zone]
|
38
|
-
time_zone = time_zone.tzinfo.name
|
39
|
-
else
|
40
|
-
raise "Unrecognized time zone"
|
41
|
-
end
|
42
|
-
query =
|
43
|
-
case connection.adapter_name
|
44
|
-
when "MySQL", "Mysql2"
|
45
|
-
case field
|
46
|
-
when "day_of_week" # Sunday = 0, Monday = 1, etc
|
47
|
-
# use CONCAT for consistent return type (String)
|
48
|
-
["DAYOFWEEK(CONVERT_TZ(#{column}, '+00:00', ?)) - 1", time_zone]
|
49
|
-
when "hour_of_day"
|
50
|
-
["EXTRACT(HOUR from CONVERT_TZ(#{column}, '+00:00', ?))", time_zone]
|
51
|
-
when "week"
|
52
|
-
["CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL (DAYOFWEEK(CONVERT_TZ(#{column}, '+00:00', ?)) - 1) DAY), '+00:00', ?), '%Y-%m-%d 00:00:00'), ?, '+00:00')", time_zone, time_zone, time_zone]
|
53
|
-
else
|
54
|
-
format =
|
55
|
-
case field
|
56
|
-
when "second"
|
57
|
-
"%Y-%m-%d %H:%i:%S"
|
58
|
-
when "minute"
|
59
|
-
"%Y-%m-%d %H:%i:00"
|
60
|
-
when "hour"
|
61
|
-
"%Y-%m-%d %H:00:00"
|
62
|
-
when "day"
|
63
|
-
"%Y-%m-%d 00:00:00"
|
64
|
-
when "month"
|
65
|
-
"%Y-%m-01 00:00:00"
|
66
|
-
else # year
|
67
|
-
"%Y-01-01 00:00:00"
|
68
|
-
end
|
69
|
-
|
70
|
-
["CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(#{column}, '+00:00', ?), '#{format}'), ?, '+00:00')", time_zone, time_zone]
|
71
|
-
end
|
72
|
-
when "PostgreSQL"
|
73
|
-
case field
|
74
|
-
when "day_of_week"
|
75
|
-
["EXTRACT(DOW from #{column}::timestamptz AT TIME ZONE ?)", time_zone]
|
76
|
-
when "hour_of_day"
|
77
|
-
["EXTRACT(HOUR from #{column}::timestamptz AT TIME ZONE ?)", time_zone]
|
78
|
-
when "week" # start on Sunday, not PostgreSQL default Monday
|
79
|
-
["(DATE_TRUNC('#{field}', (#{column}::timestamptz + INTERVAL '1 day') AT TIME ZONE ?) - INTERVAL '1 day') AT TIME ZONE ?", time_zone, time_zone]
|
80
|
-
else
|
81
|
-
["DATE_TRUNC('#{field}', #{column}::timestamptz AT TIME ZONE ?) AT TIME ZONE ?", time_zone, time_zone]
|
82
|
-
end
|
83
|
-
else
|
84
|
-
raise "Connection adapter not supported: #{connection.adapter_name}"
|
85
|
-
end
|
86
|
-
|
87
|
-
if args[2] # zeros
|
88
|
-
if time_fields.include?(field)
|
89
|
-
range = args[2]
|
90
|
-
unless range.is_a?(Range)
|
91
|
-
raise "Expecting a range"
|
92
|
-
end
|
93
|
-
|
94
|
-
# determine start time
|
95
|
-
time = range.first.in_time_zone(time_zone)
|
96
|
-
starts_at =
|
97
|
-
case field
|
98
|
-
when "second"
|
99
|
-
time.change(:usec => 0)
|
100
|
-
when "minute"
|
101
|
-
time.change(:sec => 0)
|
102
|
-
when "hour"
|
103
|
-
time.change(:min => 0)
|
104
|
-
when "day"
|
105
|
-
time.beginning_of_day
|
106
|
-
when "week"
|
107
|
-
time.beginning_of_week(:sunday)
|
108
|
-
when "month"
|
109
|
-
time.beginning_of_month
|
110
|
-
else # year
|
111
|
-
time.beginning_of_year
|
112
|
-
end
|
113
|
-
|
114
|
-
series = [starts_at]
|
115
|
-
|
116
|
-
step = 1.send(field)
|
117
|
-
|
118
|
-
while range.cover?(series.last + step)
|
119
|
-
series << series.last + step
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
derived_table =
|
124
|
-
case connection.adapter_name
|
125
|
-
when "PostgreSQL"
|
126
|
-
case field
|
127
|
-
when "day_of_week", "hour_of_day"
|
128
|
-
max = field == "day_of_week" ? 6 : 23
|
129
|
-
"SELECT generate_series(0, #{max}, 1) AS #{field}"
|
130
|
-
else
|
131
|
-
sanitize_sql_array(["SELECT (generate_series(CAST(? AS timestamptz) AT TIME ZONE ?, ?, ?) AT TIME ZONE ?) AS #{field}", starts_at, time_zone, series.last, "1 #{field}", time_zone])
|
132
|
-
end
|
133
|
-
else # MySQL
|
134
|
-
case field
|
135
|
-
when "day_of_week", "hour_of_day"
|
136
|
-
max = field == "day_of_week" ? 6 : 23
|
137
|
-
(0..max).map{|i| "SELECT #{i} AS #{field}" }.join(" UNION ")
|
138
|
-
else
|
139
|
-
sanitize_sql_array([series.map{|i| "SELECT CAST(? AS DATETIME) AS #{field}" }.join(" UNION ")] + series)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
joins("RIGHT OUTER JOIN (#{derived_table}) groupdate_series ON groupdate_series.#{field} = (#{sanitize_sql_array(query)})").group(Groupdate::OrderHack.new("groupdate_series.#{field}", field))
|
144
|
-
else
|
145
|
-
group(Groupdate::OrderHack.new(sanitize_sql_array(query), field))
|
146
|
-
end
|
147
|
-
}
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
class OrderHack < String
|
153
|
-
attr_reader :field
|
154
|
-
|
155
|
-
def initialize(str, field)
|
156
|
-
super(str)
|
157
|
-
@field = field
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
ActiveRecord::Base.send :include, Groupdate
|
4
|
+
ActiveRecord::Base.send :include, Groupdate::Scopes
|
163
5
|
|
164
6
|
# hack for **unfixed** rails issue
|
165
7
|
# https://github.com/rails/rails/issues/7121
|
166
8
|
module ActiveRecord
|
167
9
|
module Calculations
|
168
10
|
|
11
|
+
private
|
12
|
+
|
169
13
|
def column_alias_for_with_hack(*keys)
|
170
14
|
if keys.first.is_a?(Groupdate::OrderHack)
|
171
15
|
keys.first.field
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "groupdate/order_hack"
|
2
|
+
require "groupdate/series"
|
3
|
+
require "active_record"
|
4
|
+
|
5
|
+
module Groupdate
|
6
|
+
module Scopes
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
# Pattern from kaminari
|
10
|
+
# https://github.com/amatsuda/kaminari/blob/master/lib/kaminari/models/active_record_extension.rb
|
11
|
+
included do
|
12
|
+
# Future subclasses will pick up the model extension
|
13
|
+
class << self
|
14
|
+
def inherited_with_groupdate(kls) #:nodoc:
|
15
|
+
inherited_without_groupdate kls
|
16
|
+
kls.send(:include, ClassMethods) if kls.superclass == ActiveRecord::Base
|
17
|
+
end
|
18
|
+
alias_method_chain :inherited, :groupdate
|
19
|
+
end
|
20
|
+
|
21
|
+
# Existing subclasses pick up the model extension as well
|
22
|
+
self.descendants.each do |kls|
|
23
|
+
kls.send(:include, ClassMethods) if kls.superclass == ActiveRecord::Base
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
extend ActiveSupport::Concern
|
29
|
+
|
30
|
+
included do
|
31
|
+
# Field list from
|
32
|
+
# http://www.postgresql.org/docs/9.1/static/functions-datetime.html
|
33
|
+
time_fields = %w(second minute hour day week month year)
|
34
|
+
number_fields = %w(day_of_week hour_of_day)
|
35
|
+
(time_fields + number_fields).each do |field|
|
36
|
+
# no define_singleton_method in ruby 1.8
|
37
|
+
(class << self; self end).send :define_method, :"group_by_#{field}" do |*args|
|
38
|
+
column = connection.quote_table_name(args[0])
|
39
|
+
time_zone = args[1] || Time.zone || "Etc/UTC"
|
40
|
+
if time_zone.is_a?(ActiveSupport::TimeZone) or time_zone = ActiveSupport::TimeZone[time_zone]
|
41
|
+
time_zone = time_zone.tzinfo.name
|
42
|
+
else
|
43
|
+
raise "Unrecognized time zone"
|
44
|
+
end
|
45
|
+
query =
|
46
|
+
case connection.adapter_name
|
47
|
+
when "MySQL", "Mysql2"
|
48
|
+
case field
|
49
|
+
when "day_of_week" # Sunday = 0, Monday = 1, etc
|
50
|
+
# use CONCAT for consistent return type (String)
|
51
|
+
["DAYOFWEEK(CONVERT_TZ(#{column}, '+00:00', ?)) - 1", time_zone]
|
52
|
+
when "hour_of_day"
|
53
|
+
["EXTRACT(HOUR from CONVERT_TZ(#{column}, '+00:00', ?))", time_zone]
|
54
|
+
when "week"
|
55
|
+
["CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL (DAYOFWEEK(CONVERT_TZ(#{column}, '+00:00', ?)) - 1) DAY), '+00:00', ?), '%Y-%m-%d 00:00:00'), ?, '+00:00')", time_zone, time_zone, time_zone]
|
56
|
+
else
|
57
|
+
format =
|
58
|
+
case field
|
59
|
+
when "second"
|
60
|
+
"%Y-%m-%d %H:%i:%S"
|
61
|
+
when "minute"
|
62
|
+
"%Y-%m-%d %H:%i:00"
|
63
|
+
when "hour"
|
64
|
+
"%Y-%m-%d %H:00:00"
|
65
|
+
when "day"
|
66
|
+
"%Y-%m-%d 00:00:00"
|
67
|
+
when "month"
|
68
|
+
"%Y-%m-01 00:00:00"
|
69
|
+
else # year
|
70
|
+
"%Y-01-01 00:00:00"
|
71
|
+
end
|
72
|
+
|
73
|
+
["CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(#{column}, '+00:00', ?), '#{format}'), ?, '+00:00')", time_zone, time_zone]
|
74
|
+
end
|
75
|
+
when "PostgreSQL"
|
76
|
+
case field
|
77
|
+
when "day_of_week"
|
78
|
+
["EXTRACT(DOW from #{column}::timestamptz AT TIME ZONE ?)", time_zone]
|
79
|
+
when "hour_of_day"
|
80
|
+
["EXTRACT(HOUR from #{column}::timestamptz AT TIME ZONE ?)", time_zone]
|
81
|
+
when "week" # start on Sunday, not PostgreSQL default Monday
|
82
|
+
["(DATE_TRUNC('#{field}', (#{column}::timestamptz + INTERVAL '1 day') AT TIME ZONE ?) - INTERVAL '1 day') AT TIME ZONE ?", time_zone, time_zone]
|
83
|
+
else
|
84
|
+
["DATE_TRUNC('#{field}', #{column}::timestamptz AT TIME ZONE ?) AT TIME ZONE ?", time_zone, time_zone]
|
85
|
+
end
|
86
|
+
else
|
87
|
+
raise "Connection adapter not supported: #{connection.adapter_name}"
|
88
|
+
end
|
89
|
+
|
90
|
+
group = group(Groupdate::OrderHack.new(sanitize_sql_array(query), field, time_zone))
|
91
|
+
if args[2]
|
92
|
+
Series.new(group, field, column, time_zone, args[2])
|
93
|
+
else
|
94
|
+
group
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Groupdate
|
2
|
+
class Series
|
3
|
+
|
4
|
+
def initialize(relation, field, column, time_zone, time_range)
|
5
|
+
@relation = relation
|
6
|
+
if time_range.is_a?(Range)
|
7
|
+
@relation = relation.where("#{column} BETWEEN ? AND ?", time_range.first, time_range.last)
|
8
|
+
end
|
9
|
+
@field = field
|
10
|
+
@time_zone = time_zone
|
11
|
+
@time_range = time_range
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_series(count)
|
15
|
+
cast_method =
|
16
|
+
case @field
|
17
|
+
when "day_of_week", "hour_of_day"
|
18
|
+
lambda{|k| k.to_i }
|
19
|
+
else
|
20
|
+
lambda{|k| k.is_a?(Time) ? k : Time.parse(k) }
|
21
|
+
end
|
22
|
+
|
23
|
+
count = Hash[count.map do |k, v|
|
24
|
+
[cast_method.call(k), v]
|
25
|
+
end]
|
26
|
+
|
27
|
+
series =
|
28
|
+
case @field
|
29
|
+
when "day_of_week"
|
30
|
+
0..6
|
31
|
+
when "hour_of_day"
|
32
|
+
0..23
|
33
|
+
else
|
34
|
+
time_range =
|
35
|
+
if @time_range.is_a?(Range)
|
36
|
+
@time_range
|
37
|
+
else
|
38
|
+
# use first and last values
|
39
|
+
sorted_keys = count.keys.sort
|
40
|
+
sorted_keys.first..sorted_keys.last
|
41
|
+
end
|
42
|
+
|
43
|
+
# determine start time
|
44
|
+
time = time_range.first.in_time_zone(@time_zone)
|
45
|
+
starts_at =
|
46
|
+
case @field
|
47
|
+
when "second"
|
48
|
+
time.change(:usec => 0)
|
49
|
+
when "minute"
|
50
|
+
time.change(:sec => 0)
|
51
|
+
when "hour"
|
52
|
+
time.change(:min => 0)
|
53
|
+
when "day"
|
54
|
+
time.beginning_of_day
|
55
|
+
when "week"
|
56
|
+
time.beginning_of_week(:sunday)
|
57
|
+
when "month"
|
58
|
+
time.beginning_of_month
|
59
|
+
else # year
|
60
|
+
time.beginning_of_year
|
61
|
+
end
|
62
|
+
|
63
|
+
series = [starts_at]
|
64
|
+
|
65
|
+
step = 1.send(@field)
|
66
|
+
|
67
|
+
while time_range.cover?(series.last + step)
|
68
|
+
series << series.last + step
|
69
|
+
end
|
70
|
+
|
71
|
+
series.map{|s| s.to_time }
|
72
|
+
end
|
73
|
+
|
74
|
+
Hash[series.map do |k|
|
75
|
+
[k, count[k] || 0]
|
76
|
+
end]
|
77
|
+
end
|
78
|
+
|
79
|
+
def method_missing(method, *args, &block)
|
80
|
+
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/calculations.rb
|
81
|
+
if ActiveRecord::Calculations.method_defined?(method)
|
82
|
+
build_series(@relation.send(method, *args, &block))
|
83
|
+
else
|
84
|
+
raise NoMethodError, "valid methods are: #{ActiveRecord::Calculations.instance_methods.join(", ")}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end # Series
|
89
|
+
end
|
data/lib/groupdate/version.rb
CHANGED
data/test/groupdate_test.rb
CHANGED
@@ -122,6 +122,11 @@ describe Groupdate do
|
|
122
122
|
assert_group_number_tz :day_of_week, "2013-03-03 00:00:00 UTC", 6
|
123
123
|
end
|
124
124
|
|
125
|
+
it "works with previous scopes" do
|
126
|
+
create_user "2013-05-01 00:00:00 UTC"
|
127
|
+
assert_equal({}, User.where("id = 0").group_by_day(:created_at).count)
|
128
|
+
end
|
129
|
+
|
125
130
|
describe "returns zeros" do
|
126
131
|
|
127
132
|
it "group_by_second" do
|
@@ -172,7 +177,7 @@ describe Groupdate do
|
|
172
177
|
create_user "2013-05-01 00:00:00 UTC"
|
173
178
|
expected = {}
|
174
179
|
7.times do |n|
|
175
|
-
expected[
|
180
|
+
expected[n] = n == 3 ? 1 : 0
|
176
181
|
end
|
177
182
|
assert_equal(expected, User.group_by_day_of_week(:created_at, Time.zone, true).count(:created_at))
|
178
183
|
end
|
@@ -181,7 +186,7 @@ describe Groupdate do
|
|
181
186
|
create_user "2013-05-01 20:00:00 UTC"
|
182
187
|
expected = {}
|
183
188
|
24.times do |n|
|
184
|
-
expected[
|
189
|
+
expected[n] = n == 20 ? 1 : 0
|
185
190
|
end
|
186
191
|
assert_equal(expected, User.group_by_hour_of_day(:created_at, Time.zone, true).count(:created_at))
|
187
192
|
end
|
@@ -189,9 +194,17 @@ describe Groupdate do
|
|
189
194
|
it "excludes end" do
|
190
195
|
create_user "2013-05-02 00:00:00 UTC"
|
191
196
|
expected = {
|
192
|
-
|
197
|
+
Time.parse("2013-05-01 00:00:00 UTC") => 0
|
198
|
+
}
|
199
|
+
assert_equal(expected, User.group_by_day(:created_at, Time.zone, Time.parse("2013-05-01 00:00:00 UTC")...Time.parse("2013-05-02 00:00:00 UTC")).count)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "works with previous scopes" do
|
203
|
+
create_user "2013-05-01 00:00:00 UTC"
|
204
|
+
expected = {
|
205
|
+
Time.parse("2013-05-01 00:00:00 UTC") => 0
|
193
206
|
}
|
194
|
-
assert_equal(expected, User.group_by_day(:created_at, Time.zone, Time.parse("2013-05-01 00:00:00 UTC")
|
207
|
+
assert_equal(expected, User.where("id = 0").group_by_day(:created_at, Time.zone, Time.parse("2013-05-01 00:00:00 UTC")..Time.parse("2013-05-01 23:59:59 UTC")).count)
|
195
208
|
end
|
196
209
|
|
197
210
|
end
|
@@ -203,7 +216,7 @@ describe Groupdate do
|
|
203
216
|
|
204
217
|
def assert_group(method, created_at, key, time_zone = nil)
|
205
218
|
create_user created_at
|
206
|
-
assert_equal(ordered_hash({time_key(key) => 1}), User.send(:"group_by_#{method}", :created_at, time_zone).order(method).count)
|
219
|
+
assert_equal(ordered_hash({time_key(key) => 1}), User.send(:"group_by_#{method}", :created_at, time_zone).order(method.to_s).count)
|
207
220
|
end
|
208
221
|
|
209
222
|
def assert_group_tz(method, created_at, key)
|
@@ -212,7 +225,7 @@ describe Groupdate do
|
|
212
225
|
|
213
226
|
def assert_group_number(method, created_at, key, time_zone = nil)
|
214
227
|
create_user created_at
|
215
|
-
assert_equal(ordered_hash({number_key(key) => 1}), User.send(:"group_by_#{method}", :created_at, time_zone).order(method).count)
|
228
|
+
assert_equal(ordered_hash({number_key(key) => 1}), User.send(:"group_by_#{method}", :created_at, time_zone).order(method.to_s).count)
|
216
229
|
end
|
217
230
|
|
218
231
|
def assert_group_number_tz(method, created_at, key)
|
@@ -223,9 +236,9 @@ describe Groupdate do
|
|
223
236
|
create_user created_at
|
224
237
|
expected = {}
|
225
238
|
keys.each_with_index do |key, i|
|
226
|
-
expected[
|
239
|
+
expected[Time.parse(key)] = i == 1 ? 1 : 0
|
227
240
|
end
|
228
|
-
assert_equal(expected, User.send(:"group_by_#{method}", :created_at, time_zone, Time.parse(range_start)..Time.parse(range_end)).
|
241
|
+
assert_equal(expected, User.send(:"group_by_#{method}", :created_at, time_zone, Time.parse(range_start)..Time.parse(range_end)).count)
|
229
242
|
end
|
230
243
|
|
231
244
|
def assert_zeros_tz(method, created_at, keys, range_start, range_end)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: groupdate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05-
|
11
|
+
date: 2013-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -109,6 +109,9 @@ files:
|
|
109
109
|
- Rakefile
|
110
110
|
- groupdate.gemspec
|
111
111
|
- lib/groupdate.rb
|
112
|
+
- lib/groupdate/order_hack.rb
|
113
|
+
- lib/groupdate/scopes.rb
|
114
|
+
- lib/groupdate/series.rb
|
112
115
|
- lib/groupdate/version.rb
|
113
116
|
- test/groupdate_test.rb
|
114
117
|
homepage: ''
|