activerecord 4.2.0.beta4 → 4.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +107 -34
  3. data/lib/active_record/aggregations.rb +2 -2
  4. data/lib/active_record/associations.rb +1 -1
  5. data/lib/active_record/associations/alias_tracker.rb +3 -12
  6. data/lib/active_record/associations/association_scope.rb +1 -2
  7. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
  8. data/lib/active_record/associations/collection_association.rb +29 -6
  9. data/lib/active_record/associations/has_many_association.rb +1 -1
  10. data/lib/active_record/associations/has_many_through_association.rb +2 -2
  11. data/lib/active_record/associations/join_dependency.rb +1 -1
  12. data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
  13. data/lib/active_record/associations/preloader.rb +1 -0
  14. data/lib/active_record/associations/preloader/association.rb +3 -8
  15. data/lib/active_record/associations/preloader/through_association.rb +1 -0
  16. data/lib/active_record/associations/singular_association.rb +2 -1
  17. data/lib/active_record/attribute_methods.rb +2 -2
  18. data/lib/active_record/attribute_methods/dirty.rb +1 -1
  19. data/lib/active_record/attribute_methods/primary_key.rb +2 -1
  20. data/lib/active_record/attribute_methods/read.rb +13 -5
  21. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
  22. data/lib/active_record/attribute_set.rb +7 -11
  23. data/lib/active_record/attribute_set/builder.rb +66 -17
  24. data/lib/active_record/attributes.rb +20 -3
  25. data/lib/active_record/connection_adapters/abstract/database_statements.rb +0 -4
  26. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -3
  27. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +25 -24
  28. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +9 -3
  29. data/lib/active_record/connection_adapters/abstract_adapter.rb +9 -7
  30. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +25 -13
  31. data/lib/active_record/connection_adapters/connection_specification.rb +1 -1
  32. data/lib/active_record/connection_adapters/mysql2_adapter.rb +6 -0
  33. data/lib/active_record/connection_adapters/mysql_adapter.rb +6 -2
  34. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +0 -4
  35. data/lib/active_record/connection_adapters/postgresql/quoting.rb +6 -16
  36. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +29 -7
  37. data/lib/active_record/connection_adapters/postgresql/utils.rb +15 -4
  38. data/lib/active_record/connection_adapters/postgresql_adapter.rb +15 -6
  39. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +5 -7
  40. data/lib/active_record/connection_handling.rb +1 -1
  41. data/lib/active_record/core.rb +5 -3
  42. data/lib/active_record/enum.rb +1 -1
  43. data/lib/active_record/errors.rb +21 -0
  44. data/lib/active_record/fixtures.rb +4 -2
  45. data/lib/active_record/gem_version.rb +1 -1
  46. data/lib/active_record/locking/optimistic.rb +1 -1
  47. data/lib/active_record/migration.rb +15 -4
  48. data/lib/active_record/model_schema.rb +8 -4
  49. data/lib/active_record/persistence.rb +5 -5
  50. data/lib/active_record/railtie.rb +0 -2
  51. data/lib/active_record/railties/databases.rake +7 -6
  52. data/lib/active_record/reflection.rb +2 -2
  53. data/lib/active_record/relation.rb +21 -13
  54. data/lib/active_record/relation/calculations.rb +1 -0
  55. data/lib/active_record/relation/finder_methods.rb +8 -5
  56. data/lib/active_record/relation/merger.rb +0 -12
  57. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  58. data/lib/active_record/relation/query_methods.rb +30 -18
  59. data/lib/active_record/sanitization.rb +4 -1
  60. data/lib/active_record/schema_dumper.rb +1 -6
  61. data/lib/active_record/scoping/named.rb +1 -1
  62. data/lib/active_record/statement_cache.rb +21 -10
  63. data/lib/active_record/tasks/database_tasks.rb +17 -2
  64. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -0
  65. data/lib/active_record/type.rb +1 -0
  66. data/lib/active_record/type/big_integer.rb +13 -0
  67. data/lib/active_record/type/decimal_without_scale.rb +2 -2
  68. data/lib/active_record/type/hash_lookup_type_map.rb +5 -7
  69. data/lib/active_record/type/integer.rb +29 -1
  70. data/lib/active_record/type/serialized.rb +1 -1
  71. data/lib/active_record/type/string.rb +4 -4
  72. data/lib/active_record/type/type_map.rb +23 -7
  73. data/lib/active_record/validations.rb +4 -3
  74. data/lib/active_record/validations/uniqueness.rb +1 -1
  75. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +3 -0
  76. data/lib/rails/generators/active_record/migration/templates/migration.rb +6 -0
  77. metadata +15 -20
@@ -115,7 +115,7 @@ module ActiveRecord
115
115
  end
116
116
 
117
117
  def clear
118
- cache.values.each do |hash|
118
+ cache.each_value do |hash|
119
119
  dealloc hash[:stmt]
120
120
  end
121
121
  cache.clear
@@ -179,10 +179,6 @@ module ActiveRecord
179
179
  true
180
180
  end
181
181
 
182
- def supports_add_column?
183
- true
184
- end
185
-
186
182
  def supports_views?
187
183
  true
188
184
  end
@@ -270,7 +266,9 @@ module ActiveRecord
270
266
  end
271
267
  end
272
268
 
269
+ #--
273
270
  # DATABASE STATEMENTS ======================================
271
+ #++
274
272
 
275
273
  def explain(arel, binds = [])
276
274
  sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
@@ -451,12 +449,12 @@ module ActiveRecord
451
449
 
452
450
  # See: http://www.sqlite.org/lang_altertable.html
453
451
  # SQLite has an additional restriction on the ALTER TABLE statement
454
- def valid_alter_table_options( type, options)
452
+ def valid_alter_table_type?(type)
455
453
  type.to_sym != :primary_key
456
454
  end
457
455
 
458
456
  def add_column(table_name, column_name, type, options = {}) #:nodoc:
459
- if supports_add_column? && valid_alter_table_options( type, options )
457
+ if valid_alter_table_type?(type)
460
458
  super(table_name, column_name, type, options)
461
459
  else
462
460
  alter_table(table_name) do |definition|
@@ -1,6 +1,6 @@
1
1
  module ActiveRecord
2
2
  module ConnectionHandling
3
- RAILS_ENV = -> { Rails.env if defined?(Rails) }
3
+ RAILS_ENV = -> { (Rails.env if defined?(Rails)) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] }
4
4
  DEFAULT_ENV = -> { RAILS_ENV.call || "default_env" }
5
5
 
6
6
  # Establishes the connection to the database. Accepts a hash as input where
@@ -155,6 +155,8 @@ module ActiveRecord
155
155
  raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
156
156
  end
157
157
  record
158
+ rescue RangeError
159
+ raise RecordNotFound, "Couldn't find #{name} with an out of range value for '#{primary_key}'"
158
160
  end
159
161
 
160
162
  def find_by(*args)
@@ -185,6 +187,8 @@ module ActiveRecord
185
187
  s.execute(hash.values, self, connection).first
186
188
  rescue TypeError => e
187
189
  raise ActiveRecord::StatementInvalid.new(e.message, e)
190
+ rescue RangeError
191
+ nil
188
192
  end
189
193
  end
190
194
 
@@ -266,7 +270,7 @@ module ActiveRecord
266
270
  # # Instantiates a single new object
267
271
  # User.new(first_name: 'Jamie')
268
272
  def initialize(attributes = nil, options = {})
269
- @attributes = self.class.default_attributes.dup
273
+ @attributes = self.class._default_attributes.dup
270
274
 
271
275
  init_internals
272
276
  initialize_internals_callback
@@ -532,8 +536,6 @@ module ActiveRecord
532
536
  end
533
537
 
534
538
  def init_internals
535
- @attributes.ensure_initialized(self.class.primary_key)
536
-
537
539
  @aggregation_cache = {}
538
540
  @association_cache = {}
539
541
  @readonly = false
@@ -142,7 +142,7 @@ module ActiveRecord
142
142
  private
143
143
  def save_changed_attribute(attr_name, old)
144
144
  if (mapping = self.class.defined_enums[attr_name.to_s])
145
- value = read_attribute(attr_name)
145
+ value = _read_attribute(attr_name)
146
146
  if attribute_changed?(attr_name)
147
147
  if mapping[old] == value
148
148
  clear_attribute_changes([attr_name])
@@ -52,10 +52,29 @@ module ActiveRecord
52
52
  # Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be
53
53
  # saved because record is invalid.
54
54
  class RecordNotSaved < ActiveRecordError
55
+ attr_reader :record
56
+
57
+ def initialize(message, record = nil)
58
+ @record = record
59
+ super(message)
60
+ end
55
61
  end
56
62
 
57
63
  # Raised by ActiveRecord::Base.destroy! when a call to destroy would return false.
64
+ #
65
+ # begin
66
+ # complex_operation_that_internally_calls_destroy!
67
+ # rescue ActiveRecord::RecordNotDestroyed => invalid
68
+ # puts invalid.record.errors
69
+ # end
70
+ #
58
71
  class RecordNotDestroyed < ActiveRecordError
72
+ attr_reader :record
73
+
74
+ def initialize(record)
75
+ @record = record
76
+ super()
77
+ end
59
78
  end
60
79
 
61
80
  # Superclass for all database execution errors.
@@ -177,6 +196,7 @@ module ActiveRecord
177
196
  # offending attribute.
178
197
  class AttributeAssignmentError < ActiveRecordError
179
198
  attr_reader :exception, :attribute
199
+
180
200
  def initialize(message, exception, attribute)
181
201
  super(message)
182
202
  @exception = exception
@@ -189,6 +209,7 @@ module ActiveRecord
189
209
  # objects, each corresponding to the error while assigning to an attribute.
190
210
  class MultiparameterAssignmentErrors < ActiveRecordError
191
211
  attr_reader :errors
212
+
192
213
  def initialize(errors)
193
214
  @errors = errors
194
215
  end
@@ -649,7 +649,7 @@ module ActiveRecord
649
649
  model_class
650
650
  end
651
651
 
652
- reflection_class._reflections.values.each do |association|
652
+ reflection_class._reflections.each_value do |association|
653
653
  case association.macro
654
654
  when :belongs_to
655
655
  # Do not replace association name with association foreign key if they are named the same
@@ -806,7 +806,9 @@ module ActiveRecord
806
806
 
807
807
  def find
808
808
  if model_class
809
- model_class.find(fixture[model_class.primary_key])
809
+ model_class.unscoped do
810
+ model_class.find(fixture[model_class.primary_key])
811
+ end
810
812
  else
811
813
  raise FixtureClassNotFound, "No class attached to find."
812
814
  end
@@ -8,7 +8,7 @@ module ActiveRecord
8
8
  MAJOR = 4
9
9
  MINOR = 2
10
10
  TINY = 0
11
- PRE = "beta4"
11
+ PRE = "rc1"
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
14
  end
@@ -120,7 +120,7 @@ module ActiveRecord
120
120
  if locking_enabled?
121
121
  column_name = self.class.locking_column
122
122
  column = self.class.columns_hash[column_name]
123
- substitute = self.class.connection.substitute_at(column, relation.bind_values.length)
123
+ substitute = self.class.connection.substitute_at(column)
124
124
 
125
125
  relation = relation.where(self.class.arel_table[column_name].eq(substitute))
126
126
  relation.bind_values << [column, self[column_name].to_i]
@@ -184,8 +184,8 @@ module ActiveRecord
184
184
  # you wish to downgrade. Alternatively, you can also use the STEP option if you
185
185
  # wish to rollback last few migrations. <tt>rake db:migrate STEP=2</tt> will rollback
186
186
  # the latest two migrations.
187
- #
188
- # If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
187
+ #
188
+ # If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
189
189
  # that step will fail and you'll have some manual work to do.
190
190
  #
191
191
  # == Database support
@@ -394,8 +394,15 @@ module ActiveRecord
394
394
  end
395
395
 
396
396
  def load_schema_if_pending!
397
- if ActiveRecord::Migrator.needs_migration?
398
- ActiveRecord::Tasks::DatabaseTasks.load_schema_current
397
+ if ActiveRecord::Migrator.needs_migration? || !ActiveRecord::Migrator.any_migrations?
398
+ # Roundrip to Rake to allow plugins to hook into database initialization.
399
+ FileUtils.cd Rails.root do
400
+ current_config = Base.connection_config
401
+ Base.clear_all_connections!
402
+ system("bin/rake db:test:prepare")
403
+ # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
404
+ Base.establish_connection(current_config)
405
+ end
399
406
  check_pending!
400
407
  end
401
408
  end
@@ -848,6 +855,10 @@ module ActiveRecord
848
855
  (migrations(migrations_paths).collect(&:version) - get_all_versions(connection)).size > 0
849
856
  end
850
857
 
858
+ def any_migrations?
859
+ migrations(migrations_paths).any?
860
+ end
861
+
851
862
  def last_version
852
863
  last_migration.version
853
864
  end
@@ -231,7 +231,7 @@ module ActiveRecord
231
231
  end
232
232
 
233
233
  def attributes_builder # :nodoc:
234
- @attributes_builder ||= AttributeSet::Builder.new(column_types)
234
+ @attributes_builder ||= AttributeSet::Builder.new(column_types, primary_key)
235
235
  end
236
236
 
237
237
  def column_types # :nodoc:
@@ -247,12 +247,12 @@ module ActiveRecord
247
247
  # Returns a hash where the keys are column names and the values are
248
248
  # default values when instantiating the AR object for this table.
249
249
  def column_defaults
250
- default_attributes.to_hash
250
+ _default_attributes.to_hash
251
251
  end
252
252
 
253
- def default_attributes # :nodoc:
253
+ def _default_attributes # :nodoc:
254
254
  @default_attributes ||= attributes_builder.build_from_database(
255
- columns_hash.transform_values(&:default))
255
+ raw_default_values)
256
256
  end
257
257
 
258
258
  # Returns an array of column names as strings.
@@ -331,6 +331,10 @@ module ActiveRecord
331
331
  base.table_name
332
332
  end
333
333
  end
334
+
335
+ def raw_default_values
336
+ columns_hash.transform_values(&:default)
337
+ end
334
338
  end
335
339
  end
336
340
  end
@@ -139,7 +139,7 @@ module ActiveRecord
139
139
  # Attributes marked as readonly are silently ignored if the record is
140
140
  # being updated.
141
141
  def save!(*)
142
- create_or_update || raise(RecordNotSaved)
142
+ create_or_update || raise(RecordNotSaved.new(nil, self))
143
143
  end
144
144
 
145
145
  # Deletes the record in the database and freezes this instance to
@@ -166,7 +166,7 @@ module ActiveRecord
166
166
  # and <tt>destroy</tt> returns +false+. See
167
167
  # ActiveRecord::Callbacks for further details.
168
168
  def destroy
169
- raise ReadOnlyRecord if readonly?
169
+ raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly?
170
170
  destroy_associations
171
171
  destroy_row if persisted?
172
172
  @destroyed = true
@@ -181,7 +181,7 @@ module ActiveRecord
181
181
  # and <tt>destroy!</tt> raises ActiveRecord::RecordNotDestroyed. See
182
182
  # ActiveRecord::Callbacks for further details.
183
183
  def destroy!
184
- destroy || raise(ActiveRecord::RecordNotDestroyed)
184
+ destroy || raise(ActiveRecord::RecordNotDestroyed, self)
185
185
  end
186
186
 
187
187
  # Returns an instance of the specified +klass+ with the attributes of the
@@ -487,7 +487,7 @@ module ActiveRecord
487
487
  def relation_for_destroy
488
488
  pk = self.class.primary_key
489
489
  column = self.class.columns_hash[pk]
490
- substitute = self.class.connection.substitute_at(column, 0)
490
+ substitute = self.class.connection.substitute_at(column)
491
491
 
492
492
  relation = self.class.unscoped.where(
493
493
  self.class.arel_table[pk].eq(substitute))
@@ -497,7 +497,7 @@ module ActiveRecord
497
497
  end
498
498
 
499
499
  def create_or_update
500
- raise ReadOnlyRecord if readonly?
500
+ raise ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly?
501
501
  result = new_record? ? _create_record : _update_record
502
502
  result != false
503
503
  end
@@ -36,8 +36,6 @@ module ActiveRecord
36
36
  config.eager_load_namespaces << ActiveRecord
37
37
 
38
38
  rake_tasks do
39
- require "active_record/base"
40
-
41
39
  namespace :db do
42
40
  task :load_config do
43
41
  ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
@@ -196,7 +196,8 @@ db_namespace = namespace :db do
196
196
  fixture_files = if ENV['FIXTURES']
197
197
  ENV['FIXTURES'].split(',')
198
198
  else
199
- Pathname.glob("#{fixtures_dir}/**/*.yml").map {|f| f.basename.sub_ext('').to_s }
199
+ # The use of String#[] here is to support namespaced fixtures
200
+ Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] }
200
201
  end
201
202
 
202
203
  ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_files)
@@ -304,7 +305,7 @@ db_namespace = namespace :db do
304
305
  end
305
306
 
306
307
  # desc "Recreate the test database from the current schema"
307
- task :load => %w(db:test:deprecated db:test:purge) do
308
+ task :load => %w(db:test:purge) do
308
309
  case ActiveRecord::Base.schema_format
309
310
  when :ruby
310
311
  db_namespace["test:load_schema"].invoke
@@ -314,7 +315,7 @@ db_namespace = namespace :db do
314
315
  end
315
316
 
316
317
  # desc "Recreate the test database from an existent schema.rb file"
317
- task :load_schema => %w(db:test:deprecated db:test:purge) do
318
+ task :load_schema => %w(db:test:purge) do
318
319
  begin
319
320
  should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
320
321
  ActiveRecord::Schema.verbose = false
@@ -327,7 +328,7 @@ db_namespace = namespace :db do
327
328
  end
328
329
 
329
330
  # desc "Recreate the test database from an existent structure.sql file"
330
- task :load_structure => %w(db:test:deprecated db:test:purge) do
331
+ task :load_structure => %w(db:test:purge) do
331
332
  ActiveRecord::Tasks::DatabaseTasks.load_schema_for ActiveRecord::Base.configurations['test'], :sql, ENV['SCHEMA']
332
333
  end
333
334
 
@@ -348,12 +349,12 @@ db_namespace = namespace :db do
348
349
  task :clone_structure => %w(db:test:deprecated db:structure:dump db:test:load_structure)
349
350
 
350
351
  # desc "Empty the test database"
351
- task :purge => %w(db:test:deprecated environment load_config) do
352
+ task :purge => %w(environment load_config) do
352
353
  ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations['test']
353
354
  end
354
355
 
355
356
  # desc 'Check for pending migrations and load the test schema'
356
- task :prepare => %w(db:test:deprecated environment load_config) do
357
+ task :prepare => %w(environment load_config) do
357
358
  unless ActiveRecord::Base.configurations.blank?
358
359
  db_namespace['test:load'].invoke
359
360
  end
@@ -63,7 +63,7 @@ module ActiveRecord
63
63
 
64
64
  # Returns a Hash of name of the reflection as the key and a AssociationReflection as the value.
65
65
  #
66
- # Account.reflections # => {balance: AggregateReflection}
66
+ # Account.reflections # => {"balance" => AggregateReflection}
67
67
  #
68
68
  # @api public
69
69
  def reflections
@@ -287,7 +287,7 @@ module ActiveRecord
287
287
  def association_scope_cache(conn, owner)
288
288
  key = conn.prepared_statements
289
289
  if polymorphic?
290
- key = [key, owner.read_attribute(@foreign_type)]
290
+ key = [key, owner._read_attribute(@foreign_type)]
291
291
  end
292
292
  @association_scope_cache[key] ||= @scope_lock.synchronize {
293
293
  @association_scope_cache[key] ||= yield
@@ -79,22 +79,26 @@ module ActiveRecord
79
79
  scope.unscope!(where: @klass.inheritance_column)
80
80
  end
81
81
 
82
- um = scope.where(@klass.arel_table[@klass.primary_key].eq(id_was || id)).arel.compile_update(substitutes, @klass.primary_key)
82
+ relation = scope.where(@klass.primary_key => (id_was || id))
83
+ bvs = binds + relation.bind_values
84
+ um = relation
85
+ .arel
86
+ .compile_update(substitutes, @klass.primary_key)
83
87
 
84
88
  @klass.connection.update(
85
89
  um,
86
90
  'SQL',
87
- binds)
91
+ bvs,
92
+ )
88
93
  end
89
94
 
90
95
  def substitute_values(values) # :nodoc:
91
- substitutes = values.sort_by { |arel_attr,_| arel_attr.name }
92
- binds = substitutes.map do |arel_attr, value|
96
+ binds = values.map do |arel_attr, value|
93
97
  [@klass.columns_hash[arel_attr.name], value]
94
98
  end
95
99
 
96
- substitutes.each_with_index do |tuple, i|
97
- tuple[1] = @klass.connection.substitute_at(binds[i][0], i)
100
+ substitutes = values.each_with_index.map do |(arel_attr, _), i|
101
+ [arel_attr, @klass.connection.substitute_at(binds[i][0])]
98
102
  end
99
103
 
100
104
  [substitutes, binds]
@@ -300,11 +304,11 @@ module ActiveRecord
300
304
  klass.current_scope = previous
301
305
  end
302
306
 
303
- # Updates all records with details given if they match a set of conditions supplied, limits and order can
304
- # also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the
305
- # database. It does not instantiate the involved models and it does not trigger Active Record callbacks
306
- # or validations. Values passed to `update_all` will not go through ActiveRecord's type-casting behavior.
307
- # It should receive only values that can be passed as-is to the SQL database.
307
+ # Updates all records in the current relation with details given. This method constructs a single SQL UPDATE
308
+ # statement and sends it straight to the database. It does not instantiate the involved models and it does not
309
+ # trigger Active Record callbacks or validations. Values passed to `update_all` will not go through
310
+ # ActiveRecord's type-casting behavior. It should receive only values that can be passed as-is to the SQL
311
+ # database.
308
312
  #
309
313
  # ==== Parameters
310
314
  #
@@ -337,7 +341,7 @@ module ActiveRecord
337
341
  stmt.wheres = arel.constraints
338
342
  end
339
343
 
340
- bvs = bind_values + arel.bind_values
344
+ bvs = arel.bind_values + bind_values
341
345
  @klass.connection.update stmt, 'SQL', bvs
342
346
  end
343
347
 
@@ -635,7 +639,7 @@ module ActiveRecord
635
639
 
636
640
  preload = preload_values
637
641
  preload += includes_values unless eager_loading?
638
- preloader = ActiveRecord::Associations::Preloader.new
642
+ preloader = build_preloader
639
643
  preload.each do |associations|
640
644
  preloader.preload @records, associations
641
645
  end
@@ -646,6 +650,10 @@ module ActiveRecord
646
650
  @records
647
651
  end
648
652
 
653
+ def build_preloader
654
+ ActiveRecord::Associations::Preloader.new
655
+ end
656
+
649
657
  def references_eager_loaded_tables?
650
658
  joined_tables = arel.join_sources.map do |join|
651
659
  if join.is_a?(Arel::Nodes::StringJoin)