Class: ActiveRecord::Associations::AssociationScope

Inherits:
Object
  • Object
show all
Defined in:
lib/store_base_sti_class_for_4_0.rb,
lib/store_base_sti_class_for_4_1.rb,
lib/store_base_sti_class_for_4_2.rb,
lib/store_base_sti_class_for_5_0.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.get_bind_values(owner, chain) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/store_base_sti_class_for_4_2.rb', line 191

def self.get_bind_values(owner, chain)
  binds = []
  last_reflection = chain.last

  binds << last_reflection.join_id_for(owner)
  if last_reflection.type
    # START PATCH
    # original: binds << owner.class.base_class.name
    binds << (ActiveRecord::Base.store_base_sti_class ? owner.class.base_class.name : owner.class.name)
    # END PATCH
  end

  chain.each_cons(2).each do |reflection, next_reflection|
    if reflection.type
      # START PATCH
      # original: binds << next_reflection.klass.base_class.name
      binds << (ActiveRecord::Base.store_base_sti_class ? next_reflection.klass.base_class.name : next_reflection.klass.name)
      # END PATCH
    end
  end
  binds
end

Instance Method Details

#add_constraints(scope, owner, assoc_klass, refl, tracker) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/store_base_sti_class_for_4_0.rb', line 201

def add_constraints(scope)
  tables = construct_tables

  chain.each_with_index do |reflection, i|
    table, foreign_table = tables.shift, tables.first

    if reflection.source_macro == :has_and_belongs_to_many
      join_table = tables.shift

      scope = scope.joins(join(
        join_table,
        table[reflection.association_primary_key].
          eq(join_table[reflection.association_foreign_key])
      ))

      table, foreign_table = join_table, tables.first
    end

    if reflection.source_macro == :belongs_to
      if reflection.options[:polymorphic]
        key = reflection.association_primary_key(self.klass)
      else
        key = reflection.association_primary_key
      end

      foreign_key = reflection.foreign_key
    else
      key         = reflection.foreign_key
      foreign_key = reflection.active_record_primary_key
    end

    if reflection == chain.last
      bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key]
      scope    = scope.where(table[key].eq(bind_val))

      if reflection.type
        # START PATCH
        # original: value = owner.class.base_class.name

        unless ActiveRecord::Base.store_base_sti_class
          value = owner.class.name
        else
          value = owner.class.base_class.name
        end

        # END PATCH
        bind_val = bind scope, table.table_name, reflection.type.to_s, value
        scope    = scope.where(table[reflection.type].eq(bind_val))
      end
    else
      constraint = table[key].eq(foreign_table[foreign_key])

      if reflection.type
        # START PATCH
        # original: type = chain[i + 1].klass.base_class.name
        #           constraint = constraint.and(table[reflection.type].eq(type))

        if ActiveRecord::Base.store_base_sti_class
          type = chain[i + 1].klass.base_class.name
          constraint = constraint.and(table[reflection.type].eq(type))
        else
          klass = chain[i + 1].klass
          constraint = constraint.and(table[reflection.type].in(([klass] + klass.descendants).map(&:name)))
        end

        # END PATCH
      end

      scope = scope.joins(join(foreign_table, constraint))
    end

    is_first_chain = i == 0
    klass = is_first_chain ? self.klass : reflection.klass

    # Exclude the scope of the association itself, because that
    # was already merged in the #scope method.
    scope_chain[i].each do |scope_chain_item|
      item  = eval_scope(klass, scope_chain_item)

      if scope_chain_item == self.reflection.scope
        scope.merge! item.except(:where, :includes)
      end

      if is_first_chain
        scope.includes! item.includes_values
      end

      scope.where_values += item.where_values
      scope.order_values |= item.order_values
    end
  end

  scope
end