rails_select_on_includes 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 63afc846674a71d9b60199a542ac6842ad09c134
4
- data.tar.gz: f7c43c0cbfdae603b95c066f6e6575ad161b1e90
3
+ metadata.gz: 5f26d06137a196f73e828264c19083cbd2c40dd6
4
+ data.tar.gz: 5bc21a1aa9c61a595c87afcdd6d6d6e2e00a192f
5
5
  SHA512:
6
- metadata.gz: 3e469be7fdc9d1b389a3a20647baf475dfe8f625f84ee560b4d9c348af5b87db06064402e3453fce553fbe8bc3675def092a4c93bf6211872aaf73d61611f8f4
7
- data.tar.gz: c7cf417cc7771e2d9248e02092678e214d4012a6a003a67680e3ba29125898dd697c18f31ee5bee8d5288e6a6e6e829c9dbc4d434a3ab6033f505ad86d95b60e
6
+ metadata.gz: f2ca94a77cdac843e6b63b2ed5e1ab6158c6165dd4782d4fae5ec72bcce839c94dac1c8b552aec9624df2501e780d9a4b4a9a1f63e682155313ff50cb26e1707
7
+ data.tar.gz: f299a77e138a5dc2acaafa8f72d8b656e94894cfd5b7d13f17ea6d38e651c3f8bf0365cb19e302d73435f714aaaec35af4430ff4c808645241b75f9949e93dec
@@ -1,141 +1,272 @@
1
1
  require 'active_support/deprecation'
2
2
  require 'active_support/core_ext/string/filters'
3
3
 
4
- module ActiveRecord
5
- module Associations
6
- class JoinDependency # :nodoc:
7
- class Aliases # :nodoc:
8
- def initialize(tables)
9
- @tables = tables
10
- @alias_cache = tables.each_with_object({}) { |table,h|
11
- h[table.node] = table.columns.each_with_object({}) { |column,i|
12
- i[column.name] = column.alias
13
- }
14
- }
15
- @name_and_alias_cache = tables.each_with_object({}) { |table,h|
16
- h[table.node] = table.columns.map { |column|
17
- [column.name, column.alias]
18
- }
19
- @base_class_node_aliases ||= h[table.node] if table.node.is_a?(ActiveRecord::Associations::JoinDependency::JoinBase)
20
- }
21
-
22
- @virtual_attributes_names = []
23
- end
24
- # valid formats are:
25
- # 1 'table_name.column' or 'table_name.column as column_1' will be parsed! distinct on can be used also
26
- # 2 {table_name: column} or { table_name: [column1, column2] }
27
- # 3 table_name: 2
28
- def update_aliases_to_select_values( select_values )
29
- return if select_values.blank?
30
- select_values.each do |sv|
31
- # if sv is symbol that we assume that its a base table column and it will be aliased and added as usual
32
- # all we need is some specials joins+select from related tables
33
- if sv.is_a?(Hash)
34
- flatten_hash_values(sv).each{|sub_sv| @base_class_node_aliases << [sub_sv, sub_sv]; @virtual_attributes_names << sub_sv }
35
- elsif sv.is_a?(String)
36
- # this is the case of long raw select
37
- sv.split( ", " ).each do |sub_sv|
38
- if sub_sv[/.+ as .+/i]
39
- selected_column = sub_sv[/ as .+/i][4..-1]
40
- @base_class_node_aliases << [selected_column, selected_column]
41
- @virtual_attributes_names << selected_column
42
- elsif sub_sv[/.+\.[^\*]+/]
43
- selected_column = sub_sv[/\..+/][1..-1]
44
- @base_class_node_aliases << [selected_column, selected_column]
45
- @virtual_attributes_names << selected_column
46
- end
47
- end
48
- end
4
+ ::ActiveRecord::Associations::JoinDependency::Aliases.class_eval do
5
+ def initialize(tables)
6
+ @tables = tables
7
+ @alias_cache = tables.each_with_object({}) { |table,h|
8
+ h[table.node] = table.columns.each_with_object({}) { |column,i|
9
+ i[column.name] = column.alias
10
+ }
11
+ }
12
+ @name_and_alias_cache = tables.each_with_object({}) { |table,h|
13
+ h[table.node] = table.columns.map { |column|
14
+ [column.name, column.alias]
15
+ }
16
+ @base_class_node_aliases ||= h[table.node] if table.node.is_a?(ActiveRecord::Associations::JoinDependency::JoinBase)
17
+ }
18
+
19
+ @virtual_attributes_names = []
20
+ end
21
+ # valid formats are:
22
+ # 1 'table_name.column' or 'table_name.column as column_1' will be parsed! distinct on can be used also
23
+ # 2 {table_name: column} or { table_name: [column1, column2] }
24
+ # 3 table_name: 2
25
+ def update_aliases_to_select_values( select_values )
26
+ return if select_values.blank?
27
+ select_values.each do |sv|
28
+ # if sv is symbol that we assume that its a base table column and it will be aliased and added as usual
29
+ # all we need is some specials joins+select from related tables
30
+ if sv.is_a?(Hash)
31
+ flatten_hash_values(sv).each{|sub_sv| @base_class_node_aliases << [sub_sv, sub_sv]; @virtual_attributes_names << sub_sv }
32
+ elsif sv.is_a?(String)
33
+ # this is the case of long raw select
34
+ sv.split( ", " ).each do |sub_sv|
35
+ if sub_sv[/.+ as .+/i]
36
+ selected_column = sub_sv[/ as .+/i][4..-1]
37
+ @base_class_node_aliases << [selected_column, selected_column]
38
+ @virtual_attributes_names << selected_column
39
+ elsif sub_sv[/.+\.[^\*]+/]
40
+ selected_column = sub_sv[/\..+/][1..-1]
41
+ @base_class_node_aliases << [selected_column, selected_column]
42
+ @virtual_attributes_names << selected_column
49
43
  end
50
44
  end
45
+ end
46
+ end
47
+ end
51
48
 
52
- def slice_selected_attr_types( column_types )
53
- column_types.slice( *@virtual_attributes_names )
54
- end
49
+ def slice_selected_attr_types( column_types )
50
+ column_types.slice( *@virtual_attributes_names )
51
+ end
55
52
 
56
- private
57
- def flatten_hash_values( some_hash )
58
- some_hash.values.map{ |value| value.is_a?(Hash) ? flatten_hash_values( value ) : value }.flatten
59
- end
60
- end
53
+ private
54
+ def flatten_hash_values( some_hash )
55
+ some_hash.values.map{ |value| value.is_a?(Hash) ? flatten_hash_values( value ) : value }.flatten
56
+ end
57
+ end
61
58
 
62
- class JoinPart
63
- def instantiate(row, aliases, column_types = {}, &block)
64
- base_klass.instantiate(extract_record(row, aliases), column_types, &block)
65
- end
66
- end
59
+ ::ActiveRecord::Associations::JoinDependency::JoinPart.class_eval do
60
+ def instantiate(row, aliases, column_types = {}, &block)
61
+ base_klass.instantiate(extract_record(row, aliases), column_types, &block)
62
+ end
63
+ end
67
64
 
68
- def instantiate(result_set, aliases)
69
- primary_key = aliases.column_alias(join_root, join_root.primary_key)
70
-
71
- seen = Hash.new { |i, object_id|
72
- i[object_id] = Hash.new { |j, child_class|
73
- j[child_class] = {}
74
- }
75
- }
76
-
77
- model_cache = Hash.new { |h,klass| h[klass] = {} }
78
- parents = model_cache[join_root]
79
- column_aliases = aliases.column_aliases join_root
80
-
81
- message_bus = ActiveSupport::Notifications.instrumenter
82
-
83
- payload = {
84
- record_count: result_set.length,
85
- class_name: join_root.base_klass.name
86
- }
87
-
88
- message_bus.instrument('instantiation.active_record', payload) do
89
- result_set.each { |row_hash|
90
- parent_key = primary_key ? row_hash[primary_key] : row_hash
91
- # DISTINCTION PART > join_root.instantiate(row_hash, column_aliases, aliases.slice_selected_attr_types( result_set.column_types ) )
92
- # PREVIOUS > join_root.instantiate(row_hash, column_aliases )
93
- parent = parents[parent_key] ||= join_root.instantiate(row_hash, column_aliases, aliases.slice_selected_attr_types( result_set.column_types ) )
94
- construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
95
- }
96
- end
97
- parents.values
98
- end
65
+ ::ActiveRecord::Associations::JoinDependency.class_eval do
66
+ def instantiate(result_set, aliases)
67
+ primary_key = aliases.column_alias(join_root, join_root.primary_key)
99
68
 
100
- end
69
+ seen = Hash.new { |i, object_id|
70
+ i[object_id] = Hash.new { |j, child_class|
71
+ j[child_class] = {}
72
+ }
73
+ }
74
+
75
+ model_cache = Hash.new { |h,klass| h[klass] = {} }
76
+ parents = model_cache[join_root]
77
+ column_aliases = aliases.column_aliases join_root
78
+
79
+ message_bus = ActiveSupport::Notifications.instrumenter
80
+
81
+ payload = {
82
+ record_count: result_set.length,
83
+ class_name: join_root.base_klass.name
84
+ }
85
+
86
+ message_bus.instrument('instantiation.active_record', payload) do
87
+ result_set.each { |row_hash|
88
+ parent_key = primary_key ? row_hash[primary_key] : row_hash
89
+ # DISTINCTION PART > join_root.instantiate(row_hash, column_aliases, aliases.slice_selected_attr_types( result_set.column_types ) )
90
+ # PREVIOUS > join_root.instantiate(row_hash, column_aliases )
91
+ parent = parents[parent_key] ||= join_root.instantiate(row_hash, column_aliases, aliases.slice_selected_attr_types( result_set.column_types ) )
92
+ construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
93
+ }
101
94
  end
95
+ parents.values
96
+ end
102
97
  end
103
98
 
104
- module ActiveRecord
105
- module FinderMethods
106
-
107
- def find_with_associations
108
- # NOTE: the JoinDependency constructed here needs to know about
109
- # any joins already present in `self`, so pass them in
110
- #
111
- # failing to do so means that in cases like activerecord/test/cases/associations/inner_join_association_test.rb:136
112
- # incorrect SQL is generated. In that case, the join dependency for
113
- # SpecialCategorizations is constructed without knowledge of the
114
- # preexisting join in joins_values to categorizations (by way of
115
- # the `has_many :through` for categories).
116
- #
117
- join_dependency = construct_join_dependency(joins_values)
118
-
119
- aliases = join_dependency.aliases
120
- relation = select aliases.columns
121
- relation = apply_join_dependency(relation, join_dependency)
122
-
123
- if block_given?
124
- yield relation
125
- else
126
- if ActiveRecord::NullRelation === relation
127
- []
128
- else
129
- arel = relation.arel
130
- rows = connection.select_all(arel, 'SQL', relation.bound_attributes)
131
- #1 DISTINCTION IS HERE:
132
- # now we gently mokey-patching existing column aliases with select values
133
- aliases.update_aliases_to_select_values(values[:select]) unless values[:select].blank?
134
-
135
- join_dependency.instantiate(rows, aliases)
136
- end
137
- end
99
+
100
+ ::ActiveRecord::FinderMethods.class_eval do
101
+ def find_with_associations
102
+ # NOTE: the JoinDependency constructed here needs to know about
103
+ # any joins already present in `self`, so pass them in
104
+ #
105
+ # failing to do so means that in cases like activerecord/test/cases/associations/inner_join_association_test.rb:136
106
+ # incorrect SQL is generated. In that case, the join dependency for
107
+ # SpecialCategorizations is constructed without knowledge of the
108
+ # preexisting join in joins_values to categorizations (by way of
109
+ # the `has_many :through` for categories).
110
+ #
111
+ join_dependency = construct_join_dependency(joins_values)
112
+
113
+ aliases = join_dependency.aliases
114
+ relation = select aliases.columns
115
+ relation = apply_join_dependency(relation, join_dependency)
116
+
117
+ if block_given?
118
+ yield relation
119
+ else
120
+ if ActiveRecord::NullRelation === relation
121
+ []
122
+ else
123
+ arel = relation.arel
124
+ rows = connection.select_all(arel, 'SQL', relation.bound_attributes)
125
+ #1 DISTINCTION IS HERE:
126
+ # now we gently mokey-patching existing column aliases with select values
127
+ aliases.update_aliases_to_select_values(values[:select]) unless values[:select].blank?
128
+
129
+ join_dependency.instantiate(rows, aliases)
130
+ end
138
131
  end
139
132
  end
140
133
  end
141
134
 
135
+ # module ActiveRecord
136
+ # module Associations
137
+ # class JoinDependency # :nodoc:
138
+ # # class Aliases # :nodoc:
139
+ # # def initialize(tables)
140
+ # # @tables = tables
141
+ # # @alias_cache = tables.each_with_object({}) { |table,h|
142
+ # # h[table.node] = table.columns.each_with_object({}) { |column,i|
143
+ # # i[column.name] = column.alias
144
+ # # }
145
+ # # }
146
+ # # @name_and_alias_cache = tables.each_with_object({}) { |table,h|
147
+ # # h[table.node] = table.columns.map { |column|
148
+ # # [column.name, column.alias]
149
+ # # }
150
+ # # @base_class_node_aliases ||= h[table.node] if table.node.is_a?(ActiveRecord::Associations::JoinDependency::JoinBase)
151
+ # # }
152
+ # #
153
+ # # @virtual_attributes_names = []
154
+ # # end
155
+ # # # valid formats are:
156
+ # # # 1 'table_name.column' or 'table_name.column as column_1' will be parsed! distinct on can be used also
157
+ # # # 2 {table_name: column} or { table_name: [column1, column2] }
158
+ # # # 3 table_name: 2
159
+ # # def update_aliases_to_select_values( select_values )
160
+ # # return if select_values.blank?
161
+ # # select_values.each do |sv|
162
+ # # # if sv is symbol that we assume that its a base table column and it will be aliased and added as usual
163
+ # # # all we need is some specials joins+select from related tables
164
+ # # if sv.is_a?(Hash)
165
+ # # flatten_hash_values(sv).each{|sub_sv| @base_class_node_aliases << [sub_sv, sub_sv]; @virtual_attributes_names << sub_sv }
166
+ # # elsif sv.is_a?(String)
167
+ # # # this is the case of long raw select
168
+ # # sv.split( ", " ).each do |sub_sv|
169
+ # # if sub_sv[/.+ as .+/i]
170
+ # # selected_column = sub_sv[/ as .+/i][4..-1]
171
+ # # @base_class_node_aliases << [selected_column, selected_column]
172
+ # # @virtual_attributes_names << selected_column
173
+ # # elsif sub_sv[/.+\.[^\*]+/]
174
+ # # selected_column = sub_sv[/\..+/][1..-1]
175
+ # # @base_class_node_aliases << [selected_column, selected_column]
176
+ # # @virtual_attributes_names << selected_column
177
+ # # end
178
+ # # end
179
+ # # end
180
+ # # end
181
+ # # end
182
+ # #
183
+ # # def slice_selected_attr_types( column_types )
184
+ # # column_types.slice( *@virtual_attributes_names )
185
+ # # end
186
+ # #
187
+ # # private
188
+ # # def flatten_hash_values( some_hash )
189
+ # # some_hash.values.map{ |value| value.is_a?(Hash) ? flatten_hash_values( value ) : value }.flatten
190
+ # # end
191
+ # # end
192
+ #
193
+ # # class JoinPart
194
+ # # def instantiate(row, aliases, column_types = {}, &block)
195
+ # # base_klass.instantiate(extract_record(row, aliases), column_types, &block)
196
+ # # end
197
+ # # end
198
+ #
199
+ # # def instantiate(result_set, aliases)
200
+ # # primary_key = aliases.column_alias(join_root, join_root.primary_key)
201
+ # #
202
+ # # seen = Hash.new { |i, object_id|
203
+ # # i[object_id] = Hash.new { |j, child_class|
204
+ # # j[child_class] = {}
205
+ # # }
206
+ # # }
207
+ # #
208
+ # # model_cache = Hash.new { |h,klass| h[klass] = {} }
209
+ # # parents = model_cache[join_root]
210
+ # # column_aliases = aliases.column_aliases join_root
211
+ # #
212
+ # # message_bus = ActiveSupport::Notifications.instrumenter
213
+ # #
214
+ # # payload = {
215
+ # # record_count: result_set.length,
216
+ # # class_name: join_root.base_klass.name
217
+ # # }
218
+ # #
219
+ # # message_bus.instrument('instantiation.active_record', payload) do
220
+ # # result_set.each { |row_hash|
221
+ # # parent_key = primary_key ? row_hash[primary_key] : row_hash
222
+ # # # DISTINCTION PART > join_root.instantiate(row_hash, column_aliases, aliases.slice_selected_attr_types( result_set.column_types ) )
223
+ # # # PREVIOUS > join_root.instantiate(row_hash, column_aliases )
224
+ # # parent = parents[parent_key] ||= join_root.instantiate(row_hash, column_aliases, aliases.slice_selected_attr_types( result_set.column_types ) )
225
+ # # construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
226
+ # # }
227
+ # # end
228
+ # # parents.values
229
+ # # end
230
+ #
231
+ # end
232
+ # end
233
+ # end
234
+
235
+ # module ActiveRecord
236
+ # module FinderMethods
237
+ #
238
+ # # def find_with_associations
239
+ # # # NOTE: the JoinDependency constructed here needs to know about
240
+ # # # any joins already present in `self`, so pass them in
241
+ # # #
242
+ # # # failing to do so means that in cases like activerecord/test/cases/associations/inner_join_association_test.rb:136
243
+ # # # incorrect SQL is generated. In that case, the join dependency for
244
+ # # # SpecialCategorizations is constructed without knowledge of the
245
+ # # # preexisting join in joins_values to categorizations (by way of
246
+ # # # the `has_many :through` for categories).
247
+ # # #
248
+ # # join_dependency = construct_join_dependency(joins_values)
249
+ # #
250
+ # # aliases = join_dependency.aliases
251
+ # # relation = select aliases.columns
252
+ # # relation = apply_join_dependency(relation, join_dependency)
253
+ # #
254
+ # # if block_given?
255
+ # # yield relation
256
+ # # else
257
+ # # if ActiveRecord::NullRelation === relation
258
+ # # []
259
+ # # else
260
+ # # arel = relation.arel
261
+ # # rows = connection.select_all(arel, 'SQL', relation.bound_attributes)
262
+ # # #1 DISTINCTION IS HERE:
263
+ # # # now we gently mokey-patching existing column aliases with select values
264
+ # # aliases.update_aliases_to_select_values(values[:select]) unless values[:select].blank?
265
+ # #
266
+ # # join_dependency.instantiate(rows, aliases)
267
+ # # end
268
+ # # end
269
+ # # end
270
+ # end
271
+ # end
272
+
@@ -1,3 +1,3 @@
1
1
  module RailsSelectOnIncludes
2
- VERSION = "0.5.2"
2
+ VERSION = "0.5.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_select_on_includes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - alekseyl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-14 00:00:00.000000000 Z
11
+ date: 2017-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord