Class: ActiveRecord::Associations::AssociationScope

Inherits:
Object
  • Object
show all
Defined in:
lib/store_base_sti_class_for_3_1.rb

Instance Method Summary collapse

Instance Method Details

#add_constraints(scope) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
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
# File 'lib/store_base_sti_class_for_3_1.rb', line 173

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]
        # START PATCH
        # This line exists to support multiple versions of AR 3.1
        # original in 3.1.3: key         = reflection.association_primary_key
        
        key = (reflection.method(:association_primary_key).arity == 0) ? reflection.association_primary_key : reflection.association_primary_key(klass)
        # END PATCH
      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

    conditions = self.conditions[i]

    if reflection == chain.last
      scope = scope.where(table[key].eq(owner[foreign_key]))

      if reflection.type
        # START PATCH
        # original: scope = scope.where(table[reflection.type].eq(owner.class.base_class.name))
        
        unless ActiveRecord::Base.store_base_sti_class
          scope = scope.where(table[reflection.type].eq(owner.class.name))
        else
          scope = scope.where(table[reflection.type].eq(owner.class.base_class.name))
        end
        
        # END PATCH
      end

      conditions.each do |condition|
        if options[:through] && condition.is_a?(Hash)
          condition = { table.name => condition }
        end

        scope = scope.where(interpolate(condition))
      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))

      unless conditions.empty?
        scope = scope.where(sanitize(conditions, table))
      end
    end
  end

  scope
end