store_base_sti_class 1.1.0 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. checksums.yaml +5 -5
  2. data/Appraisals +9 -55
  3. data/LICENSE.txt +1 -1
  4. data/README.md +37 -10
  5. data/gemfiles/rails_5.0.7.gemfile +8 -0
  6. data/gemfiles/rails_5.1.7.gemfile +8 -0
  7. data/gemfiles/rails_5.2.3.gemfile +8 -0
  8. data/gemfiles/rails_5.2.4.gemfile +8 -0
  9. data/gemfiles/rails_5.2.5.gemfile +8 -0
  10. data/gemfiles/rails_6.0.3.gemfile +8 -0
  11. data/gemfiles/rails_6.1.0.gemfile +8 -0
  12. data/lib/store_base_sti_class.rb +7 -7
  13. data/lib/store_base_sti_class/version.rb +1 -1
  14. data/lib/store_base_sti_class_for_5_0.rb +16 -0
  15. data/lib/store_base_sti_class_for_5_1.rb +16 -0
  16. data/lib/store_base_sti_class_for_5_2.rb +176 -0
  17. data/lib/store_base_sti_class_for_6_0.rb +153 -0
  18. data/lib/store_base_sti_class_for_6_1.rb +156 -0
  19. data/store_base_sti_class.gemspec +1 -2
  20. metadata +17 -176
  21. data/Gemfile.lock +0 -47
  22. data/debug.log +0 -53835
  23. data/gemfiles/rails_3.0.10.gemfile.lock +0 -45
  24. data/gemfiles/rails_3.0.11.gemfile.lock +0 -45
  25. data/gemfiles/rails_3.0.12.gemfile.lock +0 -45
  26. data/gemfiles/rails_3.0.13.gemfile.lock +0 -45
  27. data/gemfiles/rails_3.0.14.gemfile.lock +0 -45
  28. data/gemfiles/rails_3.0.15.gemfile.lock +0 -45
  29. data/gemfiles/rails_3.0.16.gemfile.lock +0 -45
  30. data/gemfiles/rails_3.0.17.gemfile.lock +0 -45
  31. data/gemfiles/rails_3.0.18.gemfile.lock +0 -45
  32. data/gemfiles/rails_3.0.19.gemfile.lock +0 -45
  33. data/gemfiles/rails_3.0.20.gemfile.lock +0 -45
  34. data/gemfiles/rails_3.0.5.gemfile.lock +0 -45
  35. data/gemfiles/rails_3.0.6.gemfile.lock +0 -45
  36. data/gemfiles/rails_3.0.7.gemfile.lock +0 -45
  37. data/gemfiles/rails_3.0.8.gemfile.lock +0 -45
  38. data/gemfiles/rails_3.0.9.gemfile.lock +0 -45
  39. data/gemfiles/rails_3.1.0.gemfile.lock +0 -49
  40. data/gemfiles/rails_3.1.10.gemfile.lock +0 -47
  41. data/gemfiles/rails_3.1.11.gemfile.lock +0 -47
  42. data/gemfiles/rails_3.1.12.gemfile.lock +0 -47
  43. data/gemfiles/rails_3.1.2.gemfile.lock +0 -47
  44. data/gemfiles/rails_3.1.3.gemfile.lock +0 -47
  45. data/gemfiles/rails_3.1.4.gemfile.lock +0 -47
  46. data/gemfiles/rails_3.1.5.gemfile.lock +0 -47
  47. data/gemfiles/rails_3.1.6.gemfile.lock +0 -47
  48. data/gemfiles/rails_3.1.7.gemfile.lock +0 -47
  49. data/gemfiles/rails_3.1.8.gemfile.lock +0 -47
  50. data/gemfiles/rails_3.1.9.gemfile.lock +0 -47
  51. data/gemfiles/rails_3.2.0.gemfile.lock +0 -47
  52. data/gemfiles/rails_3.2.1.gemfile.lock +0 -47
  53. data/gemfiles/rails_3.2.10.gemfile.lock +0 -47
  54. data/gemfiles/rails_3.2.11.gemfile.lock +0 -47
  55. data/gemfiles/rails_3.2.12.gemfile.lock +0 -47
  56. data/gemfiles/rails_3.2.13.gemfile.lock +0 -47
  57. data/gemfiles/rails_3.2.14.gemfile.lock +0 -44
  58. data/gemfiles/rails_3.2.15.gemfile.lock +0 -47
  59. data/gemfiles/rails_3.2.16.gemfile.lock +0 -47
  60. data/gemfiles/rails_3.2.17.gemfile.lock +0 -47
  61. data/gemfiles/rails_3.2.18.gemfile.lock +0 -47
  62. data/gemfiles/rails_3.2.19.gemfile.lock +0 -47
  63. data/gemfiles/rails_3.2.2.gemfile.lock +0 -47
  64. data/gemfiles/rails_3.2.20.gemfile.lock +0 -47
  65. data/gemfiles/rails_3.2.21.gemfile.lock +0 -47
  66. data/gemfiles/rails_3.2.22.gemfile.lock +0 -47
  67. data/gemfiles/rails_3.2.3.gemfile.lock +0 -47
  68. data/gemfiles/rails_3.2.4.gemfile.lock +0 -47
  69. data/gemfiles/rails_3.2.5.gemfile.lock +0 -47
  70. data/gemfiles/rails_3.2.6.gemfile.lock +0 -47
  71. data/gemfiles/rails_3.2.7.gemfile.lock +0 -47
  72. data/gemfiles/rails_3.2.8.gemfile.lock +0 -47
  73. data/gemfiles/rails_3.2.9.gemfile.lock +0 -47
  74. data/gemfiles/rails_4.0.0.gemfile +0 -7
  75. data/gemfiles/rails_4.0.0.gemfile.lock +0 -49
  76. data/gemfiles/rails_4.0.1.gemfile +0 -7
  77. data/gemfiles/rails_4.0.1.gemfile.lock +0 -49
  78. data/gemfiles/rails_4.0.10.gemfile +0 -7
  79. data/gemfiles/rails_4.0.10.gemfile.lock +0 -49
  80. data/gemfiles/rails_4.0.11.1.gemfile +0 -7
  81. data/gemfiles/rails_4.0.11.1.gemfile.lock +0 -49
  82. data/gemfiles/rails_4.0.11.gemfile +0 -7
  83. data/gemfiles/rails_4.0.11.gemfile.lock +0 -49
  84. data/gemfiles/rails_4.0.12.gemfile +0 -7
  85. data/gemfiles/rails_4.0.12.gemfile.lock +0 -49
  86. data/gemfiles/rails_4.0.13.gemfile +0 -7
  87. data/gemfiles/rails_4.0.13.gemfile.lock +0 -49
  88. data/gemfiles/rails_4.0.2.gemfile +0 -7
  89. data/gemfiles/rails_4.0.2.gemfile.lock +0 -49
  90. data/gemfiles/rails_4.0.3.gemfile +0 -7
  91. data/gemfiles/rails_4.0.3.gemfile.lock +0 -49
  92. data/gemfiles/rails_4.0.4.gemfile +0 -7
  93. data/gemfiles/rails_4.0.4.gemfile.lock +0 -49
  94. data/gemfiles/rails_4.0.5.gemfile +0 -7
  95. data/gemfiles/rails_4.0.5.gemfile.lock +0 -49
  96. data/gemfiles/rails_4.0.6.gemfile +0 -7
  97. data/gemfiles/rails_4.0.6.gemfile.lock +0 -49
  98. data/gemfiles/rails_4.0.7.gemfile +0 -7
  99. data/gemfiles/rails_4.0.7.gemfile.lock +0 -49
  100. data/gemfiles/rails_4.0.8.gemfile +0 -7
  101. data/gemfiles/rails_4.0.8.gemfile.lock +0 -49
  102. data/gemfiles/rails_4.0.9.gemfile +0 -7
  103. data/gemfiles/rails_4.0.9.gemfile.lock +0 -49
  104. data/gemfiles/rails_4.1.0.gemfile +0 -7
  105. data/gemfiles/rails_4.1.0.gemfile.lock +0 -48
  106. data/gemfiles/rails_4.1.1.gemfile +0 -7
  107. data/gemfiles/rails_4.1.1.gemfile.lock +0 -48
  108. data/gemfiles/rails_4.1.10.gemfile +0 -7
  109. data/gemfiles/rails_4.1.10.gemfile.lock +0 -48
  110. data/gemfiles/rails_4.1.11.gemfile +0 -7
  111. data/gemfiles/rails_4.1.11.gemfile.lock +0 -48
  112. data/gemfiles/rails_4.1.12.gemfile +0 -7
  113. data/gemfiles/rails_4.1.12.gemfile.lock +0 -48
  114. data/gemfiles/rails_4.1.13.gemfile +0 -7
  115. data/gemfiles/rails_4.1.13.gemfile.lock +0 -48
  116. data/gemfiles/rails_4.1.14.1.gemfile +0 -7
  117. data/gemfiles/rails_4.1.14.1.gemfile.lock +0 -48
  118. data/gemfiles/rails_4.1.14.2.gemfile +0 -7
  119. data/gemfiles/rails_4.1.14.2.gemfile.lock +0 -48
  120. data/gemfiles/rails_4.1.14.gemfile +0 -7
  121. data/gemfiles/rails_4.1.14.gemfile.lock +0 -48
  122. data/gemfiles/rails_4.1.15.gemfile +0 -7
  123. data/gemfiles/rails_4.1.15.gemfile.lock +0 -48
  124. data/gemfiles/rails_4.1.2.gemfile +0 -7
  125. data/gemfiles/rails_4.1.2.gemfile.lock +0 -48
  126. data/gemfiles/rails_4.1.3.gemfile +0 -7
  127. data/gemfiles/rails_4.1.3.gemfile.lock +0 -48
  128. data/gemfiles/rails_4.1.4.gemfile +0 -7
  129. data/gemfiles/rails_4.1.4.gemfile.lock +0 -48
  130. data/gemfiles/rails_4.1.5.gemfile +0 -7
  131. data/gemfiles/rails_4.1.5.gemfile.lock +0 -48
  132. data/gemfiles/rails_4.1.6.gemfile +0 -7
  133. data/gemfiles/rails_4.1.6.gemfile.lock +0 -48
  134. data/gemfiles/rails_4.1.7.1.gemfile +0 -7
  135. data/gemfiles/rails_4.1.7.1.gemfile.lock +0 -48
  136. data/gemfiles/rails_4.1.7.gemfile +0 -7
  137. data/gemfiles/rails_4.1.7.gemfile.lock +0 -48
  138. data/gemfiles/rails_4.1.8.gemfile +0 -7
  139. data/gemfiles/rails_4.1.8.gemfile.lock +0 -48
  140. data/gemfiles/rails_4.1.9.gemfile +0 -7
  141. data/gemfiles/rails_4.1.9.gemfile.lock +0 -48
  142. data/gemfiles/rails_4.2.0.gemfile +0 -7
  143. data/gemfiles/rails_4.2.0.gemfile.lock +0 -48
  144. data/gemfiles/rails_4.2.1.gemfile +0 -7
  145. data/gemfiles/rails_4.2.1.gemfile.lock +0 -48
  146. data/gemfiles/rails_4.2.2.gemfile +0 -7
  147. data/gemfiles/rails_4.2.2.gemfile.lock +0 -48
  148. data/gemfiles/rails_4.2.3.gemfile +0 -7
  149. data/gemfiles/rails_4.2.3.gemfile.lock +0 -48
  150. data/gemfiles/rails_4.2.4.gemfile +0 -7
  151. data/gemfiles/rails_4.2.4.gemfile.lock +0 -48
  152. data/gemfiles/rails_4.2.5.1.gemfile +0 -7
  153. data/gemfiles/rails_4.2.5.1.gemfile.lock +0 -48
  154. data/gemfiles/rails_4.2.5.2.gemfile +0 -7
  155. data/gemfiles/rails_4.2.5.2.gemfile.lock +0 -48
  156. data/gemfiles/rails_4.2.5.gemfile +0 -7
  157. data/gemfiles/rails_4.2.5.gemfile.lock +0 -48
  158. data/gemfiles/rails_4.2.6.gemfile +0 -7
  159. data/gemfiles/rails_4.2.6.gemfile.lock +0 -48
  160. data/gemfiles/rails_4.2.7.1.gemfile +0 -7
  161. data/gemfiles/rails_4.2.7.gemfile +0 -7
  162. data/gemfiles/rails_4.2.8.gemfile +0 -7
  163. data/gemfiles/rails_5.0.0.1.gemfile +0 -7
  164. data/gemfiles/rails_5.0.0.gemfile +0 -7
  165. data/gemfiles/rails_5.0.1.gemfile +0 -7
  166. data/gemfiles/rails_5.0.1.gemfile.lock +0 -48
  167. data/gemfiles/rails_5.0.2.gemfile +0 -7
  168. data/gemfiles/rails_5.0.3.gemfile +0 -7
  169. data/gemfiles/rails_5.1.0.gemfile +0 -7
  170. data/gemfiles/rails_5.1.1.gemfile +0 -7
  171. data/lib/store_base_sti_class_for_4_0.rb +0 -337
  172. data/lib/store_base_sti_class_for_4_1.rb +0 -360
  173. data/lib/store_base_sti_class_for_4_2.rb +0 -360
  174. data/storebasestiname_unittest.sql +0 -0
@@ -1,360 +0,0 @@
1
- if ActiveRecord::VERSION::STRING =~ /^4\.1/
2
- module ActiveRecord
3
-
4
- class Base
5
- class_attribute :store_base_sti_class
6
- self.store_base_sti_class = true
7
- end
8
-
9
- module Associations
10
- class Association
11
-
12
- def creation_attributes
13
- attributes = {}
14
-
15
- if (reflection.macro == :has_one || reflection.macro == :has_many) && !options[:through]
16
- attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
17
-
18
- if reflection.options[:as]
19
- # START PATCH
20
- # original:
21
- # attributes[reflection.type] = owner.class.base_class.name
22
-
23
- attributes[reflection.type] = ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name
24
-
25
- # END PATCH
26
- end
27
- end
28
-
29
- attributes
30
- end
31
- end
32
-
33
- class JoinDependency
34
- class JoinAssociation
35
- def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scope_chain, chain)
36
- joins = []
37
- tables = tables.reverse
38
-
39
- scope_chain_index = 0
40
- scope_chain = scope_chain.reverse
41
-
42
- # The chain starts with the target table, but we want to end with it here (makes
43
- # more sense in this context), so we reverse
44
- chain.reverse_each do |reflection|
45
- table = tables.shift
46
- klass = reflection.klass
47
-
48
- case reflection.source_macro
49
- when :belongs_to
50
- key = reflection.association_primary_key
51
- foreign_key = reflection.foreign_key
52
- else
53
- key = reflection.foreign_key
54
- foreign_key = reflection.active_record_primary_key
55
- end
56
-
57
- constraint = build_constraint(klass, table, key, foreign_table, foreign_key)
58
-
59
- scope_chain_items = scope_chain[scope_chain_index].map do |item|
60
- if item.is_a?(Relation)
61
- item
62
- else
63
- ActiveRecord::Relation.create(klass, table).instance_exec(node, &item)
64
- end
65
- end
66
- scope_chain_index += 1
67
-
68
- default_scope = if klass.method(:build_default_scope).arity == 0
69
- klass.send(:build_default_scope)
70
- else
71
- klass.send(:build_default_scope, ActiveRecord::Relation.create(klass, table))
72
- end
73
- scope_chain_items.concat [default_scope].compact
74
-
75
- rel = scope_chain_items.inject(scope_chain_items.shift) do |left, right|
76
- left.merge right
77
- end
78
-
79
- if reflection.type
80
- # START PATCH
81
- # original:
82
- # constraint = constraint.and table[reflection.type].eq foreign_klass.base_class.name
83
-
84
- sti_class_name = ActiveRecord::Base.store_base_sti_class ? foreign_klass.base_class.name : foreign_klass.name
85
- constraint = constraint.and table[reflection.type].eq sti_class_name
86
-
87
- # END PATCH
88
- end
89
-
90
- if rel && !rel.arel.constraints.empty?
91
- constraint = constraint.and rel.arel.constraints
92
- end
93
-
94
- joins << table.create_join(table, table.create_on(constraint), join_type)
95
-
96
- # The current table in this iteration becomes the foreign table in the next
97
- foreign_table, foreign_klass = table, klass
98
- end
99
-
100
- joins
101
- end
102
- end
103
- end
104
-
105
- class BelongsToPolymorphicAssociation
106
- private
107
-
108
- def replace_keys(record)
109
- super
110
-
111
- # START PATCH
112
- # original:
113
- # owner[reflection.foreign_type] = record.class.base_class.name
114
-
115
- owner[reflection.foreign_type] = ActiveRecord::Base.store_base_sti_class ? record.class.base_class.name : record.class.name
116
-
117
- # END PATCH
118
- end
119
- end
120
-
121
- class Preloader
122
- class Association
123
- def build_scope
124
- scope = klass.unscoped
125
-
126
- values = reflection_scope.values
127
- preload_values = preload_scope.values
128
-
129
- scope.where_values = Array(values[:where]) + Array(preload_values[:where])
130
- scope.references_values = Array(values[:references]) + Array(preload_values[:references])
131
-
132
- select_method = scope.respond_to?(:select!) ? :select! : :_select!
133
- scope.send select_method, preload_values[:select] || values[:select] || table[Arel.star]
134
- scope.includes! preload_values[:includes] || values[:includes]
135
-
136
- if preload_values.key? :order
137
- scope.order! preload_values[:order]
138
- else
139
- if values.key? :order
140
- scope.order! values[:order]
141
- end
142
- end
143
-
144
- if options[:as]
145
- # START PATCH
146
- # original:
147
- # scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name })
148
-
149
- scope.where!(klass.table_name => { reflection.type => ActiveRecord::Base.store_base_sti_class ? model.base_class.sti_name : model.sti_name })
150
-
151
- # END PATCH
152
- end
153
-
154
- scope.unscope_values = Array(values[:unscope])
155
- klass.default_scoped.merge(scope)
156
- end
157
- end
158
-
159
- module ThroughAssociation
160
- private
161
-
162
- def through_scope
163
- scope = through_reflection.klass.unscoped
164
-
165
- if options[:source_type]
166
- # BEGIN PATCH
167
- # original: scope.where! reflection.foreign_type => options[:source_type]
168
-
169
- adjusted_foreign_type = if ActiveRecord::Base.store_base_sti_class
170
- options[:source_type]
171
- else
172
- ([options[:source_type].constantize] + options[:source_type].constantize.descendants).map(&:to_s)
173
- end
174
-
175
- scope.where! reflection.foreign_type => adjusted_foreign_type
176
-
177
- # END PATCH
178
- else
179
- unless reflection_scope.where_values.empty?
180
- scope.includes_values = Array(reflection_scope.values[:includes] || options[:source])
181
- scope.where_values = reflection_scope.values[:where]
182
- end
183
-
184
- scope.references! reflection_scope.values[:references]
185
- scope.order! reflection_scope.values[:order] if scope.eager_loading?
186
- end
187
-
188
- scope
189
- end
190
- end
191
- end
192
-
193
- class AssociationScope
194
- def add_constraints(scope, owner, assoc_klass, refl, tracker)
195
- chain = refl.chain
196
- scope_chain = refl.scope_chain
197
-
198
- tables = construct_tables(chain, assoc_klass, refl, tracker)
199
-
200
- chain.each_with_index do |reflection, i|
201
- table, foreign_table = tables.shift, tables.first
202
-
203
- if reflection.source_macro == :belongs_to
204
- if reflection.options[:polymorphic]
205
- key = reflection.association_primary_key(assoc_klass)
206
- else
207
- key = reflection.association_primary_key
208
- end
209
-
210
- foreign_key = reflection.foreign_key
211
- else
212
- key = reflection.foreign_key
213
- foreign_key = reflection.active_record_primary_key
214
- end
215
-
216
- if reflection == chain.last
217
- bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key], tracker
218
- scope = scope.where(table[key].eq(bind_val))
219
-
220
- if reflection.type
221
- # START PATCH
222
- # original: value = owner.class.base_class.name
223
-
224
- if ActiveRecord::Base.store_base_sti_class
225
- value = owner.class.base_class.name
226
- else
227
- value = owner.class.name
228
- end
229
-
230
- # END PATCH
231
-
232
- bind_val = bind scope, table.table_name, reflection.type.to_s, value, tracker
233
- scope = scope.where(table[reflection.type].eq(bind_val))
234
- end
235
- else
236
- constraint = table[key].eq(foreign_table[foreign_key])
237
-
238
- if reflection.type
239
- # START PATCH
240
- # original: type = chain[i + 1].klass.base_class.name
241
- # scope = scope.where(table[reflection.type].eq(bind_val))
242
-
243
- if ActiveRecord::Base.store_base_sti_class
244
- type = chain[i + 1].klass.base_class.name
245
- scope = scope.where(table[reflection.type].eq(type))
246
- else
247
- klass = chain[i + 1].klass
248
- scope = scope.where(table[reflection.type].in(([klass] + klass.descendants).map(&:name)))
249
- end
250
-
251
- # END PATCH
252
- end
253
-
254
- scope = scope.joins(join(foreign_table, constraint))
255
- end
256
-
257
- is_first_chain = i == 0
258
- klass = is_first_chain ? assoc_klass : reflection.klass
259
-
260
- # Exclude the scope of the association itself, because that
261
- # was already merged in the #scope method.
262
- scope_chain[i].each do |scope_chain_item|
263
- item = eval_scope(klass, scope_chain_item, owner)
264
-
265
- if scope_chain_item == refl.scope
266
- scope.merge! item.except(:where, :includes, :bind)
267
- end
268
-
269
- if is_first_chain
270
- scope.includes! item.includes_values
271
- end
272
-
273
- scope.where_values += item.where_values
274
- scope.order_values |= item.order_values
275
- end
276
- end
277
-
278
- scope
279
- end
280
- end
281
-
282
- module ThroughAssociation
283
- def construct_join_attributes(*records)
284
- ensure_mutable
285
-
286
- if source_reflection.association_primary_key(reflection.klass) == reflection.klass.primary_key
287
- join_attributes = { source_reflection.name => records }
288
- else
289
- join_attributes = {
290
- source_reflection.foreign_key =>
291
- records.map { |record|
292
- record.send(source_reflection.association_primary_key(reflection.klass))
293
- }
294
- }
295
- end
296
-
297
- if options[:source_type]
298
-
299
- # START PATCH
300
- # original:
301
- # join_attributes[source_reflection.foreign_type] =
302
- # records.map { |record| record.class.base_class.name }
303
-
304
- join_attributes[source_reflection.foreign_type] =
305
- records.map { |record| ActiveRecord::Base.store_base_sti_class ? record.class.base_class.name : record.class.name }
306
-
307
- # END PATCH
308
- end
309
-
310
- if records.count == 1
311
- Hash[join_attributes.map { |k, v| [k, v.first] }]
312
- else
313
- join_attributes
314
- end
315
- end
316
-
317
- end
318
-
319
- end
320
-
321
- module Reflection
322
- class ThroughReflection
323
- def scope_chain
324
- @scope_chain ||= begin
325
- scope_chain = source_reflection.scope_chain.map(&:dup)
326
-
327
- # Add to it the scope from this reflection (if any)
328
- scope_chain.first << scope if scope
329
-
330
- through_scope_chain = through_reflection.scope_chain.map(&:dup)
331
-
332
- if options[:source_type]
333
- type = foreign_type
334
-
335
- # START PATCH
336
- # original: source_type = options[:source_type]
337
-
338
- source_type = if ActiveRecord::Base.store_base_sti_class
339
- options[:source_type]
340
- else
341
- ([options[:source_type].constantize] + options[:source_type].constantize.descendants).map(&:to_s)
342
- end
343
-
344
- # END PATCH
345
-
346
- through_scope_chain.first << lambda { |object|
347
- where(type => source_type)
348
- }
349
- end
350
-
351
- # Recursively fill out the rest of the array from the through reflection
352
- scope_chain + through_scope_chain
353
- end
354
- end
355
- end
356
-
357
- end
358
- end
359
-
360
- end
@@ -1,360 +0,0 @@
1
- require 'active_record/associations/join_dependency/join_part'
2
-
3
- if ActiveRecord::VERSION::STRING =~ /^4\.2/
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
- module Associations
12
- class Association
13
-
14
- def creation_attributes
15
- attributes = {}
16
-
17
- if (reflection.has_one? || reflection.collection?) && !options[:through]
18
- attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
19
-
20
- if reflection.options[:as]
21
- # START PATCH
22
- # original:
23
- # attributes[reflection.type] = owner.class.base_class.name
24
-
25
- attributes[reflection.type] = ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name
26
- # END PATCH
27
- end
28
- end
29
-
30
- attributes
31
- end
32
- end
33
-
34
- class JoinDependency # :nodoc:
35
- class JoinAssociation < JoinPart # :nodoc:
36
- def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scope_chain, chain)
37
- joins = []
38
- bind_values = []
39
- tables = tables.reverse
40
-
41
- scope_chain_index = 0
42
- scope_chain = scope_chain.reverse
43
-
44
- # The chain starts with the target table, but we want to end with it here (makes
45
- # more sense in this context), so we reverse
46
- chain.reverse_each do |reflection|
47
- table = tables.shift
48
- klass = reflection.klass
49
-
50
- join_keys = reflection.join_keys(klass)
51
- key = join_keys.key
52
- foreign_key = join_keys.foreign_key
53
-
54
- constraint = build_constraint(klass, table, key, foreign_table, foreign_key)
55
-
56
- scope_chain_items = scope_chain[scope_chain_index].map do |item|
57
- if item.is_a?(Relation)
58
- item
59
- else
60
- ActiveRecord::Relation.create(klass, table).instance_exec(node, &item)
61
- end
62
- end
63
- scope_chain_index += 1
64
-
65
- scope_chain_items.concat [klass.send(:build_default_scope, ActiveRecord::Relation.create(klass, table))].compact
66
-
67
- rel = scope_chain_items.inject(scope_chain_items.shift) do |left, right|
68
- left.merge right
69
- end
70
-
71
- if rel && !rel.arel.constraints.empty?
72
- bind_values.concat rel.bind_values
73
- constraint = constraint.and rel.arel.constraints
74
- end
75
-
76
- if reflection.type
77
- # START PATCH
78
- # original:
79
- # value = foreign_klass.base_class.name
80
- value = ActiveRecord::Base.store_base_sti_class ? foreign_klass.base_class.name : foreign_klass.name
81
- # END PATCH
82
- column = klass.columns_hash[reflection.type.to_s]
83
-
84
- substitute = klass.connection.substitute_at(column)
85
- bind_values.push [column, value]
86
- constraint = constraint.and table[reflection.type].eq substitute
87
- end
88
-
89
- joins << table.create_join(table, table.create_on(constraint), join_type)
90
-
91
- # The current table in this iteration becomes the foreign table in the next
92
- foreign_table, foreign_klass = table, klass
93
- end
94
-
95
- JoinInformation.new joins, bind_values
96
- end
97
- end
98
- end
99
-
100
- class BelongsToPolymorphicAssociation
101
- private
102
-
103
- def replace_keys(record)
104
- super
105
-
106
- # START PATCH
107
- # original:
108
- # owner[reflection.foreign_type] = record.class.base_class.name
109
-
110
- owner[reflection.foreign_type] = ActiveRecord::Base.store_base_sti_class ? record.class.base_class.name : record.class.name
111
-
112
- # END PATCH
113
- end
114
- end
115
-
116
- class Preloader
117
- class Association
118
-
119
- def build_scope
120
- scope = klass.unscoped
121
-
122
- values = reflection_scope.values
123
- reflection_binds = reflection_scope.bind_values
124
- preload_values = preload_scope.values
125
- preload_binds = preload_scope.bind_values
126
-
127
- scope.where_values = Array(values[:where]) + Array(preload_values[:where])
128
- scope.references_values = Array(values[:references]) + Array(preload_values[:references])
129
- scope.bind_values = (reflection_binds + preload_binds)
130
-
131
- scope._select! preload_values[:select] || values[:select] || table[Arel.star]
132
- scope.includes! preload_values[:includes] || values[:includes]
133
- scope.joins! preload_values[:joins] || values[:joins]
134
- scope.order! preload_values[:order] || values[:order]
135
-
136
- if preload_values[:readonly] || values[:readonly]
137
- scope.readonly!
138
- end
139
-
140
- if options[:as]
141
- # START PATCH
142
- # original:
143
- # scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name })
144
-
145
- scope.where!(klass.table_name => { reflection.type => ActiveRecord::Base.store_base_sti_class ? model.base_class.sti_name : model.sti_name })
146
-
147
- # END PATCH
148
- end
149
-
150
- scope.unscope_values = Array(values[:unscope])
151
- klass.default_scoped.merge(scope)
152
- end
153
- end
154
-
155
- module ThroughAssociation
156
- private
157
-
158
- def through_scope
159
- scope = through_reflection.klass.unscoped
160
-
161
- if options[:source_type]
162
- # BEGIN PATCH
163
- # original: scope.where! reflection.foreign_type => options[:source_type]
164
-
165
- adjusted_foreign_type = if ActiveRecord::Base.store_base_sti_class
166
- options[:source_type]
167
- else
168
- ([options[:source_type].constantize] + options[:source_type].constantize.descendants).map(&:to_s)
169
- end
170
-
171
- scope.where! reflection.foreign_type => adjusted_foreign_type
172
-
173
- # END PATCH
174
- else
175
- unless reflection_scope.where_values.empty?
176
- scope.includes_values = Array(reflection_scope.values[:includes] || options[:source])
177
- scope.where_values = reflection_scope.values[:where]
178
- scope.bind_values = reflection_scope.bind_values
179
- end
180
-
181
- scope.references! reflection_scope.values[:references]
182
- scope = scope.order reflection_scope.values[:order] if scope.eager_loading?
183
- end
184
-
185
- scope
186
- end
187
- end
188
- end
189
-
190
- class AssociationScope
191
- def self.get_bind_values(owner, chain)
192
- binds = []
193
- last_reflection = chain.last
194
-
195
- binds << last_reflection.join_id_for(owner)
196
- if last_reflection.type
197
- # START PATCH
198
- # original: binds << owner.class.base_class.name
199
- binds << (ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name)
200
- # END PATCH
201
- end
202
-
203
- chain.each_cons(2).each do |reflection, next_reflection|
204
- if reflection.type
205
- # START PATCH
206
- # original: binds << next_reflection.klass.base_class.name
207
- binds << (ActiveRecord::Base.store_base_sti_class ? next_reflection.klass.base_class.name : next_reflection.klass.name)
208
- # END PATCH
209
- end
210
- end
211
- binds
212
- end
213
-
214
- def next_chain_scope(scope, table, reflection, tracker, assoc_klass, foreign_table, next_reflection)
215
- join_keys = reflection.join_keys(assoc_klass)
216
- key = join_keys.key
217
- foreign_key = join_keys.foreign_key
218
-
219
- constraint = table[key].eq(foreign_table[foreign_key])
220
-
221
- if reflection.type
222
- # BEGIN PATCH
223
- # original:
224
- # value = next_reflection.klass.base_class.name
225
- # bind_val = bind scope, table.table_name, reflection.type, value, tracker
226
- # scope = scope.where(table[reflection.type].eq(bind_val))
227
- if ActiveRecord::Base.store_base_sti_class
228
- value = next_reflection.klass.base_class.name
229
- bind_val = bind scope, table.table_name, reflection.type, value, tracker
230
- scope = scope.where(table[reflection.type].eq(bind_val))
231
- else
232
- value = next_reflection.klass.name
233
- klass = next_reflection.klass
234
- scope = scope.where(table[reflection.type].in(([klass] + klass.descendants).map(&:name)))
235
- end
236
- # END PATCH
237
-
238
- end
239
-
240
- scope = scope.joins(join(foreign_table, constraint))
241
- end
242
-
243
- def last_chain_scope(scope, table, reflection, owner, tracker, assoc_klass)
244
- join_keys = reflection.join_keys(assoc_klass)
245
- key = join_keys.key
246
- foreign_key = join_keys.foreign_key
247
-
248
- bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key], tracker
249
- scope = scope.where(table[key].eq(bind_val))
250
-
251
- if reflection.type
252
- # BEGIN PATCH
253
- # original: owner.class.base_class.name
254
- value = ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name
255
- # END PATCH
256
- bind_val = bind scope, table.table_name, reflection.type, value, tracker
257
- scope = scope.where(table[reflection.type].eq(bind_val))
258
- else
259
- scope
260
- end
261
- end
262
-
263
- end
264
-
265
- module ThroughAssociation
266
- def construct_join_attributes(*records)
267
- ensure_mutable
268
-
269
- if source_reflection.association_primary_key(reflection.klass) == reflection.klass.primary_key
270
- join_attributes = { source_reflection.name => records }
271
- else
272
- join_attributes = {
273
- source_reflection.foreign_key =>
274
- records.map { |record|
275
- record.send(source_reflection.association_primary_key(reflection.klass))
276
- }
277
- }
278
- end
279
-
280
- if options[:source_type]
281
-
282
- # START PATCH
283
- # original:
284
- # join_attributes[source_reflection.foreign_type] =
285
- # records.map { |record| record.class.base_class.name }
286
-
287
- join_attributes[source_reflection.foreign_type] =
288
- records.map { |record| ActiveRecord::Base.store_base_sti_class ? record.class.base_class.name : record.class.name }
289
-
290
- # END PATCH
291
- end
292
-
293
- if records.count == 1
294
- Hash[join_attributes.map { |k, v| [k, v.first] }]
295
- else
296
- join_attributes
297
- end
298
- end
299
-
300
- end
301
-
302
- class HasManyThroughAssociation
303
-
304
- def build_through_record(record)
305
- @through_records[record.object_id] ||= begin
306
- ensure_mutable
307
-
308
- through_record = through_association.build(*options_for_through_record)
309
- through_record.send("#{source_reflection.name}=", record)
310
-
311
- # START PATCH
312
- if ActiveRecord::Base.store_base_sti_class
313
- if options[:source_type]
314
- through_record.send("#{source_reflection.foreign_type}=", options[:source_type])
315
- end
316
- end
317
- # END PATCH
318
-
319
- through_record
320
- end
321
- end
322
- end
323
- end
324
-
325
- module Reflection
326
- class ThroughReflection
327
- def scope_chain
328
- @scope_chain ||= begin
329
- scope_chain = source_reflection.scope_chain.map(&:dup)
330
-
331
- # Add to it the scope from this reflection (if any)
332
- scope_chain.first << scope if scope
333
-
334
- through_scope_chain = through_reflection.scope_chain.map(&:dup)
335
-
336
- if options[:source_type]
337
- type = foreign_type
338
- # START PATCH
339
- # original: source_type = options[:source_type]
340
- source_type = if ActiveRecord::Base.store_base_sti_class
341
- options[:source_type]
342
- else
343
- ([options[:source_type].constantize] + options[:source_type].constantize.descendants).map(&:to_s)
344
- end
345
- # END PATCH
346
- through_scope_chain.first << lambda { |object|
347
- where(type => source_type)
348
- }
349
- end
350
-
351
- # Recursively fill out the rest of the array from the through reflection
352
- scope_chain + through_scope_chain
353
- end
354
- end
355
- end
356
-
357
- end
358
- end
359
-
360
- end