store_base_sti_class 2.0.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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