aggregate_columns 0.9.7 → 0.9.8
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.
- data/lib/aggregate_columns/version.rb +1 -1
- data/lib/aggregate_columns.rb +25 -13
- data/test/rails_3_test.rb +11 -5
- metadata +62 -99
data/lib/aggregate_columns.rb
CHANGED
@@ -72,31 +72,43 @@ module AggregateColumns
|
|
72
72
|
# (and not that complicated) to make it work on ActiveRecord::Relation
|
73
73
|
# instances
|
74
74
|
assoc_reflection = reflect_on_association( association )
|
75
|
+
# TODO: this only handles single :through association
|
75
76
|
through_reflection = assoc_reflection.through_reflection
|
76
77
|
foreign_key = assoc_reflection.foreign_key
|
77
78
|
aggregate_table_name = assoc_reflection.table_name
|
78
79
|
klass = assoc_reflection.klass
|
79
80
|
join_type = options[:join_type] # TODO: check if within allowed values
|
80
81
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
82
|
+
# This is the reflection to use to "join" with main table
|
83
|
+
join_reflection = through_reflection || assoc_reflection
|
84
|
+
join_foreign_key = join_reflection.foreign_key
|
85
|
+
aggregate_rel = klass.select( "#{aggregate_expression} AS #{result_column}" ).from( aggregate_table_name )
|
86
|
+
if through_reflection
|
87
|
+
aggregate_rel = aggregate_rel.joins( "INNER JOIN #{through_reflection.table_name} ON #{through_reflection.table_name}.id = #{aggregate_table_name}.#{assoc_reflection.foreign_key}" )
|
88
|
+
end
|
89
|
+
|
90
|
+
# TODO: this only handles :conditions and in a specific way - it should
|
91
|
+
# really handle other options as well
|
92
|
+
assoc_conditions = assoc_reflection.conditions.first.first
|
93
|
+
if assoc_conditions
|
94
|
+
aggregate_rel = aggregate_rel.where( klass.send( :sanitize_sql, assoc_conditions ))
|
95
|
+
end
|
96
|
+
if through_reflection
|
97
|
+
through_conditions = through_reflection.conditions.first.first
|
98
|
+
if through_conditions
|
99
|
+
aggregate_rel = aggregate_rel.where( through_reflection.klass.send( :sanitize_sql, through_conditions ))
|
86
100
|
end
|
101
|
+
end
|
102
|
+
|
103
|
+
if join_type
|
104
|
+
aggregate_rel = aggregate_rel.select( join_foreign_key ).group( join_foreign_key )
|
87
105
|
aggregate_rel = yield( aggregate_rel ) if block_given?
|
88
106
|
rel = rel.
|
89
|
-
joins( "#{join_type.to_s.upcase} JOIN (#{aggregate_rel.to_sql}) #{result_column}_join ON #{table_name}.id = #{result_column}_join.#{
|
107
|
+
joins( "#{join_type.to_s.upcase} JOIN (#{aggregate_rel.to_sql}) #{result_column}_join ON #{table_name}.id = #{result_column}_join.#{join_foreign_key}" ).
|
90
108
|
select( result_column.to_s ).
|
91
109
|
order( "#{result_column} DESC" ) # You might reorder if you want to have it differently
|
92
110
|
else
|
93
|
-
aggregate_rel =
|
94
|
-
if through_reflection
|
95
|
-
aggregate_rel = aggregate_rel.joins( "INNER JOIN #{through_reflection.table_name} ON #{through_reflection.table_name}.id = #{aggregate_table_name}.#{assoc_reflection.foreign_key}" ).where( "#{table_name}.id = #{through_reflection.foreign_key}" )
|
96
|
-
else
|
97
|
-
aggregate_rel = aggregate_rel.where( "#{table_name}.id = #{aggregate_table_name}.#{foreign_key}" )
|
98
|
-
end
|
99
|
-
|
111
|
+
aggregate_rel = aggregate_rel.where( "#{table_name}.id = #{join_reflection.quoted_table_name}.#{join_reflection.foreign_key}" )
|
100
112
|
aggregate_rel = yield( aggregate_rel ) if block_given?
|
101
113
|
rel = rel.
|
102
114
|
select( "(#{aggregate_rel.to_sql}) AS #{result_column}" ).
|
data/test/rails_3_test.rb
CHANGED
@@ -17,6 +17,7 @@ if Rails::VERSION::MAJOR == 3
|
|
17
17
|
class Post < ActiveRecord::Base
|
18
18
|
has_many :comments
|
19
19
|
has_many :notes, :through => :comments
|
20
|
+
has_many :accepted_comments, :class_name => "Comment", :conditions => { :accepted => true }
|
20
21
|
end
|
21
22
|
|
22
23
|
class Comment < ActiveRecord::Base
|
@@ -73,7 +74,7 @@ if Rails::VERSION::MAJOR == 3
|
|
73
74
|
relation = Post.aggregate_columns( :association => :comments, :join_type => :right )
|
74
75
|
assert_equal 2, relation.select_values.count
|
75
76
|
assert relation.select_values.include?( "comment_count" )
|
76
|
-
assert_equal relation.joins_values, ["RIGHT JOIN (SELECT
|
77
|
+
assert_equal relation.joins_values, ["RIGHT JOIN (SELECT count(*) AS comment_count, post_id FROM comments GROUP BY post_id) comment_count_join ON posts.id = comment_count_join.post_id"]
|
77
78
|
assert_equal ["comment_count DESC"], relation.order_values
|
78
79
|
assert_empty relation.where_values
|
79
80
|
end
|
@@ -88,14 +89,19 @@ if Rails::VERSION::MAJOR == 3
|
|
88
89
|
relation = Post.aggregate_columns( :association => :comments, :join_type => :right ).aggregate_columns( :association => :comments ).aggregate_columns( :association => :comments, :function => :sum, :column => :vote, :result_column => :number_of_votes )
|
89
90
|
assert_empty relation.where_values
|
90
91
|
assert relation.select_values.include?( "comment_count" )
|
91
|
-
assert relation.joins_values.include?( "RIGHT JOIN (SELECT
|
92
|
+
assert relation.joins_values.include?( "RIGHT JOIN (SELECT count(*) AS comment_count, post_id FROM comments GROUP BY post_id) comment_count_join ON posts.id = comment_count_join.post_id" )
|
92
93
|
end
|
93
94
|
|
94
95
|
def test_through_association
|
95
|
-
relation = Post.aggregate_columns( :association => :notes )
|
96
|
-
assert relation.select_values.include?( "(SELECT count(*) AS note_count FROM notes INNER JOIN comments ON comments.id = notes.comment_id WHERE (posts.id = post_id)) AS note_count" )
|
96
|
+
relation = Post.aggregate_columns( :association => :notes )
|
97
|
+
assert relation.select_values.include?( "(SELECT count(*) AS note_count FROM notes INNER JOIN comments ON comments.id = notes.comment_id WHERE (posts.id = comments.post_id)) AS note_count" )
|
97
98
|
relation = Post.aggregate_columns( :association => :notes, :join_type => :right )
|
98
|
-
assert_equal relation.joins_values, ["RIGHT JOIN (SELECT
|
99
|
+
assert_equal relation.joins_values, ["RIGHT JOIN (SELECT count(*) AS note_count, post_id FROM notes INNER JOIN comments ON comments.id = notes.comment_id GROUP BY post_id) note_count_join ON posts.id = note_count_join.post_id"]
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_conditions
|
103
|
+
relation = Post.aggregate_columns( :association => :accepted_comments )
|
104
|
+
assert relation.select_values.include?( "(SELECT count(*) AS accepted_comment_count FROM comments WHERE (comments.accepted = 't') AND (posts.id = comments.post_id)) AS accepted_comment_count" )
|
99
105
|
end
|
100
106
|
end
|
101
107
|
end
|
metadata
CHANGED
@@ -1,105 +1,78 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: aggregate_columns
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.8
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 9
|
9
|
-
- 7
|
10
|
-
version: 0.9.7
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Marek Janukowicz/Starware
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-02-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: activerecord
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &7078140 !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
version: "2"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2'
|
33
22
|
type: :runtime
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: rake
|
37
23
|
prerelease: false
|
38
|
-
|
24
|
+
version_requirements: *7078140
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &7077260 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
segments:
|
45
|
-
- 0
|
46
|
-
version: "0"
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
47
33
|
type: :development
|
48
|
-
version_requirements: *id002
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: activerecord
|
51
34
|
prerelease: false
|
52
|
-
|
35
|
+
version_requirements: *7077260
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: activerecord
|
38
|
+
requirement: &7075460 !ruby/object:Gem::Requirement
|
53
39
|
none: false
|
54
|
-
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
|
58
|
-
segments:
|
59
|
-
- 2
|
60
|
-
version: "2"
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2'
|
61
44
|
type: :development
|
62
|
-
version_requirements: *id003
|
63
|
-
- !ruby/object:Gem::Dependency
|
64
|
-
name: activesupport
|
65
45
|
prerelease: false
|
66
|
-
|
46
|
+
version_requirements: *7075460
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: activesupport
|
49
|
+
requirement: &7073600 !ruby/object:Gem::Requirement
|
67
50
|
none: false
|
68
|
-
requirements:
|
69
|
-
- -
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
|
72
|
-
segments:
|
73
|
-
- 2
|
74
|
-
version: "2"
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2'
|
75
55
|
type: :development
|
76
|
-
version_requirements: *id004
|
77
|
-
- !ruby/object:Gem::Dependency
|
78
|
-
name: activerecord-nulldb-adapter
|
79
56
|
prerelease: false
|
80
|
-
|
57
|
+
version_requirements: *7073600
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: activerecord-nulldb-adapter
|
60
|
+
requirement: &7072440 !ruby/object:Gem::Requirement
|
81
61
|
none: false
|
82
|
-
requirements:
|
83
|
-
- -
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
hash: 23
|
86
|
-
segments:
|
87
|
-
- 0
|
88
|
-
- 2
|
89
|
-
- 0
|
62
|
+
requirements:
|
63
|
+
- - =
|
64
|
+
- !ruby/object:Gem::Version
|
90
65
|
version: 0.2.0
|
91
66
|
type: :development
|
92
|
-
|
93
|
-
|
94
|
-
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *7072440
|
69
|
+
description: ''
|
70
|
+
email:
|
95
71
|
- marek@janukowicz.net
|
96
72
|
executables: []
|
97
|
-
|
98
73
|
extensions: []
|
99
|
-
|
100
74
|
extra_rdoc_files: []
|
101
|
-
|
102
|
-
files:
|
75
|
+
files:
|
103
76
|
- .hgignore
|
104
77
|
- Gemfile
|
105
78
|
- README
|
@@ -110,41 +83,31 @@ files:
|
|
110
83
|
- test/rails_2_test.rb
|
111
84
|
- test/rails_3_test.rb
|
112
85
|
- test/test_helper.rb
|
113
|
-
|
114
|
-
homepage: ""
|
86
|
+
homepage: ''
|
115
87
|
licenses: []
|
116
|
-
|
117
88
|
post_install_message:
|
118
89
|
rdoc_options: []
|
119
|
-
|
120
|
-
require_paths:
|
90
|
+
require_paths:
|
121
91
|
- lib
|
122
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
93
|
none: false
|
124
|
-
requirements:
|
125
|
-
- -
|
126
|
-
- !ruby/object:Gem::Version
|
127
|
-
|
128
|
-
|
129
|
-
- 0
|
130
|
-
version: "0"
|
131
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
99
|
none: false
|
133
|
-
requirements:
|
134
|
-
- -
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
|
137
|
-
segments:
|
138
|
-
- 0
|
139
|
-
version: "0"
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
140
104
|
requirements: []
|
141
|
-
|
142
105
|
rubyforge_project:
|
143
|
-
rubygems_version: 1.
|
106
|
+
rubygems_version: 1.8.11
|
144
107
|
signing_key:
|
145
108
|
specification_version: 3
|
146
109
|
summary: Create and use aggregate columns in Rails applications
|
147
|
-
test_files:
|
110
|
+
test_files:
|
148
111
|
- test/rails_2_test.rb
|
149
112
|
- test/rails_3_test.rb
|
150
113
|
- test/test_helper.rb
|