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.
@@ -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