store_base_sti_class 2.0.1 → 3.0.0

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,367 +0,0 @@
1
- require 'active_record/associations/join_dependency/join_part'
2
-
3
- if ActiveRecord::VERSION::STRING =~ /^5\.1/
4
- module ActiveRecord
5
-
6
- class Base
7
- class_attribute :store_base_sti_class
8
- self.store_base_sti_class = true
9
- end
10
-
11
- class PredicateBuilder
12
- class AssociationQueryHandler
13
- def call(attribute, value)
14
- queries = {}
15
-
16
- table = value.associated_table
17
- if value.base_class
18
- queries[table.association_foreign_type.to_s] = ActiveRecord::Base.store_base_sti_class ? value.base_class.name : value.value.class.name
19
- end
20
-
21
- queries[table.association_foreign_key.to_s] = value.ids
22
- predicate_builder.build_from_hash(queries)
23
- end
24
- end
25
- end
26
-
27
- module Associations
28
- class Association
29
- private
30
-
31
- def creation_attributes
32
- attributes = {}
33
-
34
- if (reflection.has_one? || reflection.collection?) && !options[:through]
35
- attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
36
-
37
- if reflection.options[:as]
38
- # START PATCH
39
- # original:
40
- # attributes[reflection.type] = owner.class.base_class.name
41
-
42
- attributes[reflection.type] = ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name
43
- # END PATCH
44
- end
45
- end
46
-
47
- attributes
48
- end
49
- end
50
-
51
- class JoinDependency # :nodoc:
52
- class JoinAssociation < JoinPart # :nodoc:
53
- def join_constraints(foreign_table, foreign_klass, join_type, tables, chain)
54
- joins = []
55
- binds = []
56
- tables = tables.reverse
57
-
58
- # The chain starts with the target table, but we want to end with it here (makes
59
- # more sense in this context), so we reverse
60
- chain.reverse_each do |reflection|
61
- table = tables.shift
62
- klass = reflection.klass
63
-
64
- join_keys = reflection.join_keys
65
- key = join_keys.key
66
- foreign_key = join_keys.foreign_key
67
-
68
- constraint = build_constraint(klass, table, key, foreign_table, foreign_key)
69
-
70
- predicate_builder = PredicateBuilder.new(TableMetadata.new(klass, table))
71
- scope_chain_items = reflection.join_scopes(table, predicate_builder)
72
- klass_scope = reflection.klass_join_scope(table, predicate_builder)
73
-
74
- scope_chain_items.concat [klass_scope].compact
75
-
76
- rel = scope_chain_items.inject(scope_chain_items.shift) do |left, right|
77
- left.merge right
78
- end
79
-
80
- if rel && !rel.arel.constraints.empty?
81
- binds += rel.bound_attributes
82
- constraint = constraint.and rel.arel.constraints
83
- end
84
-
85
- if reflection.type
86
- # START PATCH
87
- # original:
88
- # value = foreign_klass.base_class.name
89
- value = ActiveRecord::Base.store_base_sti_class ? foreign_klass.base_class.name : foreign_klass.name
90
- # END PATCH
91
- column = klass.columns_hash[reflection.type.to_s]
92
-
93
- binds << Relation::QueryAttribute.new(column.name, value, klass.type_for_attribute(column.name))
94
- constraint = constraint.and klass.arel_attribute(reflection.type, table).eq(Arel::Nodes::BindParam.new)
95
- end
96
-
97
- joins << table.create_join(table, table.create_on(constraint), join_type)
98
-
99
- # The current table in this iteration becomes the foreign table in the next
100
- foreign_table, foreign_klass = table, klass
101
- end
102
-
103
- JoinInformation.new joins, binds
104
- end
105
- end
106
- end
107
-
108
- class BelongsToPolymorphicAssociation
109
- private
110
-
111
- def replace_keys(record)
112
- super
113
-
114
- # START PATCH
115
- # original:
116
- # owner[reflection.foreign_type] = record.class.base_class.name
117
-
118
- owner[reflection.foreign_type] = ActiveRecord::Base.store_base_sti_class ? record.class.base_class.name : record.class.name
119
-
120
- # END PATCH
121
- end
122
- end
123
-
124
- class Preloader
125
- class Association
126
- private
127
-
128
- def build_scope
129
- scope = klass.unscoped
130
-
131
- values = reflection_scope.values
132
- preload_values = preload_scope.values
133
-
134
- scope.where_clause = reflection_scope.where_clause + preload_scope.where_clause
135
- scope.references_values = Array(values[:references]) + Array(preload_values[:references])
136
-
137
- if preload_values[:select] || values[:select]
138
- scope._select!(preload_values[:select] || values[:select])
139
- end
140
- scope.includes! preload_values[:includes] || values[:includes]
141
- if preload_scope.joins_values.any?
142
- scope.joins!(preload_scope.joins_values)
143
- else
144
- scope.joins!(reflection_scope.joins_values)
145
- end
146
-
147
- if order_values = preload_values[:order] || values[:order]
148
- scope.order!(order_values)
149
- end
150
-
151
- if preload_values[:reordering] || values[:reordering]
152
- scope.reordering_value = true
153
- end
154
-
155
- if preload_values[:readonly] || values[:readonly]
156
- scope.readonly!
157
- end
158
-
159
- if options[:as]
160
- # START PATCH
161
- # original:
162
- # scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name })
163
-
164
- scope.where!(klass.table_name => { reflection.type => ActiveRecord::Base.store_base_sti_class ? model.base_class.sti_name : model.sti_name })
165
-
166
- # END PATCH
167
- end
168
-
169
- scope.unscope_values = Array(values[:unscope]) + Array(preload_values[:unscope])
170
- klass.default_scoped.merge(scope)
171
- end
172
- end
173
-
174
- module ThroughAssociation
175
- private
176
-
177
- def through_scope
178
- scope = through_reflection.klass.unscoped
179
-
180
- if options[:source_type]
181
- # BEGIN PATCH
182
- # original: scope.where! reflection.foreign_type => options[:source_type]
183
-
184
- adjusted_foreign_type =
185
- if ActiveRecord::Base.store_base_sti_class
186
- options[:source_type]
187
- else
188
- ([options[:source_type].constantize] + options[:source_type].constantize.descendants).map(&:to_s)
189
- end
190
-
191
- scope.where! reflection.foreign_type => adjusted_foreign_type
192
-
193
- # END PATCH
194
- else
195
- unless reflection_scope.where_clause.empty?
196
- scope.includes_values = Array(reflection_scope.values[:includes] || options[:source])
197
- scope.where_clause = reflection_scope.where_clause
198
- end
199
-
200
- scope.references! reflection_scope.values[:references]
201
- if scope.eager_loading? && order_values = reflection_scope.values[:order]
202
- scope = scope.order(order_values)
203
- end
204
- end
205
-
206
- scope
207
- end
208
- end
209
- end
210
-
211
- class AssociationScope
212
-
213
- def self.get_bind_values(owner, chain)
214
- binds = []
215
- last_reflection = chain.last
216
-
217
- binds << last_reflection.join_id_for(owner)
218
- if last_reflection.type
219
- # START PATCH
220
- # original: binds << owner.class.base_class.name
221
- binds << (ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name)
222
- # END PATCH
223
- end
224
-
225
- chain.each_cons(2).each do |reflection, next_reflection|
226
- if reflection.type
227
- # START PATCH
228
- # original: binds << next_reflection.klass.base_class.name
229
- binds << (ActiveRecord::Base.store_base_sti_class ? next_reflection.klass.base_class.name : next_reflection.klass.name)
230
- # END PATCH
231
- end
232
- end
233
- binds
234
- end
235
-
236
- private
237
-
238
- def next_chain_scope(scope, table, reflection, foreign_table, next_reflection)
239
- join_keys = reflection.join_keys
240
- key = join_keys.key
241
- foreign_key = join_keys.foreign_key
242
-
243
- constraint = table[key].eq(foreign_table[foreign_key])
244
-
245
- if reflection.type
246
- # BEGIN PATCH
247
- # original:
248
- # value = transform_value(next_reflection.klass.base_class.name)
249
- # scope = scope.where(table.name => { reflection.type => value })
250
- if ActiveRecord::Base.store_base_sti_class
251
- value = transform_value(next_reflection.klass.base_class.name)
252
- else
253
- klass = next_reflection.klass
254
- value = ([klass] + klass.descendants).map(&:name)
255
- end
256
- scope = scope.where(table.name => { reflection.type => value })
257
- # END PATCH
258
- end
259
-
260
- scope = scope.joins(join(foreign_table, constraint))
261
- end
262
-
263
- def last_chain_scope(scope, table, reflection, owner)
264
- join_keys = reflection.join_keys
265
- key = join_keys.key
266
- foreign_key = join_keys.foreign_key
267
-
268
- value = transform_value(owner[foreign_key])
269
- scope = scope.where(table.name => { key => value })
270
-
271
- if reflection.type
272
- # BEGIN PATCH
273
- # polymorphic_type = transform_value(owner.class.base_class.name)
274
- polymorphic_type = transform_value(ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name)
275
- # END PATCH
276
- scope = scope.where(table.name => { reflection.type => polymorphic_type })
277
- end
278
-
279
- scope
280
- end
281
-
282
- end
283
-
284
- module ThroughAssociation
285
- private
286
-
287
- def construct_join_attributes(*records)
288
- ensure_mutable
289
-
290
- if source_reflection.association_primary_key(reflection.klass) == reflection.klass.primary_key
291
- join_attributes = { source_reflection.name => records }
292
- else
293
- join_attributes = {
294
- source_reflection.foreign_key =>
295
- records.map { |record|
296
- record.send(source_reflection.association_primary_key(reflection.klass))
297
- }
298
- }
299
- end
300
-
301
- if options[:source_type]
302
-
303
- # START PATCH
304
- # original:
305
- # join_attributes[source_reflection.foreign_type] =
306
- # records.map { |record| record.class.base_class.name }
307
-
308
- join_attributes[source_reflection.foreign_type] =
309
- records.map { |record| ActiveRecord::Base.store_base_sti_class ? record.class.base_class.name : record.class.name }
310
-
311
- # END PATCH
312
- end
313
-
314
- if records.count == 1
315
- Hash[join_attributes.map { |k, v| [k, v.first] }]
316
- else
317
- join_attributes
318
- end
319
- end
320
- end
321
-
322
- class HasManyThroughAssociation
323
- private
324
-
325
- def build_through_record(record)
326
- @through_records[record.object_id] ||= begin
327
- ensure_mutable
328
-
329
- through_record = through_association.build(*options_for_through_record)
330
- through_record.send("#{source_reflection.name}=", record)
331
-
332
- # START PATCH
333
- if ActiveRecord::Base.store_base_sti_class
334
- if options[:source_type]
335
- through_record.send("#{source_reflection.foreign_type}=", options[:source_type])
336
- end
337
- end
338
- # END PATCH
339
-
340
- through_record
341
- end
342
- end
343
- end
344
- end
345
-
346
- module Reflection
347
- class PolymorphicReflection
348
- def source_type_info
349
- type = @previous_reflection.foreign_type
350
- source_type = @previous_reflection.options[:source_type]
351
-
352
- # START PATCH
353
- adjusted_source_type =
354
- if ActiveRecord::Base.store_base_sti_class
355
- source_type
356
- else
357
- ([source_type.constantize] + source_type.constantize.descendants).map(&:to_s)
358
- end
359
- # END PATCH
360
-
361
- lambda { |object| where(type => adjusted_source_type) }
362
- end
363
- end
364
- end
365
- end
366
-
367
- end