rails_select_on_includes 0.5.2 → 0.5.3

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