aggregate_columns 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module AggregateColumns
2
- VERSION = "0.9.7"
2
+ VERSION = "0.9.8"
3
3
  end
@@ -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
- if join_type
82
- main_foreign_key = through_reflection ? through_reflection.foreign_key : foreign_key
83
- aggregate_rel = klass.select( "#{main_foreign_key}, #{aggregate_expression} AS #{result_column}" ).from( aggregate_table_name ).group( main_foreign_key )
84
- if through_reflection
85
- aggregate_rel = aggregate_rel.joins( "INNER JOIN #{through_reflection.table_name} ON #{through_reflection.table_name}.id = #{aggregate_table_name}.#{assoc_reflection.foreign_key}" )
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.#{main_foreign_key}" ).
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 = klass.select( "#{aggregate_expression} AS #{result_column}" ).from( aggregate_table_name )
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 post_id, count(*) AS comment_count FROM comments GROUP BY post_id) comment_count_join ON posts.id = comment_count_join.post_id"]
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 post_id, count(*) AS comment_count FROM comments GROUP BY post_id) comment_count_join ON posts.id = comment_count_join.post_id" )
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 post_id, count(*) AS note_count 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"]
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
- hash: 53
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
- date: 2012-02-02 00:00:00 +01:00
19
- default_executable:
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
- prerelease: false
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
- hash: 7
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
- requirement: &id002 !ruby/object:Gem::Requirement
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
- hash: 3
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
- requirement: &id003 !ruby/object:Gem::Requirement
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
- hash: 7
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
- requirement: &id004 !ruby/object:Gem::Requirement
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
- hash: 7
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
- requirement: &id005 !ruby/object:Gem::Requirement
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
- version_requirements: *id005
93
- description: ""
94
- email:
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
- has_rdoc: true
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
- hash: 3
128
- segments:
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
- hash: 3
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.6.2
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