groupdate 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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: ''
|