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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +107 -34
- data/lib/active_record/aggregations.rb +2 -2
- data/lib/active_record/associations.rb +1 -1
- data/lib/active_record/associations/alias_tracker.rb +3 -12
- data/lib/active_record/associations/association_scope.rb +1 -2
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
- data/lib/active_record/associations/collection_association.rb +29 -6
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +2 -2
- data/lib/active_record/associations/join_dependency.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
- data/lib/active_record/associations/preloader.rb +1 -0
- data/lib/active_record/associations/preloader/association.rb +3 -8
- data/lib/active_record/associations/preloader/through_association.rb +1 -0
- data/lib/active_record/associations/singular_association.rb +2 -1
- data/lib/active_record/attribute_methods.rb +2 -2
- data/lib/active_record/attribute_methods/dirty.rb +1 -1
- data/lib/active_record/attribute_methods/primary_key.rb +2 -1
- data/lib/active_record/attribute_methods/read.rb +13 -5
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attribute_set.rb +7 -11
- data/lib/active_record/attribute_set/builder.rb +66 -17
- data/lib/active_record/attributes.rb +20 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +0 -4
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +25 -24
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +9 -3
- data/lib/active_record/connection_adapters/abstract_adapter.rb +9 -7
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +25 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +6 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +6 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +0 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +6 -16
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +29 -7
- data/lib/active_record/connection_adapters/postgresql/utils.rb +15 -4
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +15 -6
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +5 -7
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +5 -3
- data/lib/active_record/enum.rb +1 -1
- data/lib/active_record/errors.rb +21 -0
- data/lib/active_record/fixtures.rb +4 -2
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/migration.rb +15 -4
- data/lib/active_record/model_schema.rb +8 -4
- data/lib/active_record/persistence.rb +5 -5
- data/lib/active_record/railtie.rb +0 -2
- data/lib/active_record/railties/databases.rake +7 -6
- data/lib/active_record/reflection.rb +2 -2
- data/lib/active_record/relation.rb +21 -13
- data/lib/active_record/relation/calculations.rb +1 -0
- data/lib/active_record/relation/finder_methods.rb +8 -5
- data/lib/active_record/relation/merger.rb +0 -12
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +30 -18
- data/lib/active_record/sanitization.rb +4 -1
- data/lib/active_record/schema_dumper.rb +1 -6
- data/lib/active_record/scoping/named.rb +1 -1
- data/lib/active_record/statement_cache.rb +21 -10
- data/lib/active_record/tasks/database_tasks.rb +17 -2
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -0
- data/lib/active_record/type.rb +1 -0
- data/lib/active_record/type/big_integer.rb +13 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -7
- data/lib/active_record/type/integer.rb +29 -1
- data/lib/active_record/type/serialized.rb +1 -1
- data/lib/active_record/type/string.rb +4 -4
- data/lib/active_record/type/type_map.rb +23 -7
- data/lib/active_record/validations.rb +4 -3
- data/lib/active_record/validations/uniqueness.rb +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +3 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb +6 -0
- metadata +15 -20
@@ -115,7 +115,7 @@ module ActiveRecord
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def clear
|
118
|
-
cache.
|
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
|
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
|
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
|
data/lib/active_record/core.rb
CHANGED
@@ -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.
|
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
|
data/lib/active_record/enum.rb
CHANGED
@@ -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 =
|
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])
|
data/lib/active_record/errors.rb
CHANGED
@@ -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.
|
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.
|
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
|
@@ -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
|
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
|
-
|
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
|
-
|
250
|
+
_default_attributes.to_hash
|
251
251
|
end
|
252
252
|
|
253
|
-
def
|
253
|
+
def _default_attributes # :nodoc:
|
254
254
|
@default_attributes ||= attributes_builder.build_from_database(
|
255
|
-
|
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
|
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
|
-
|
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:
|
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:
|
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:
|
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(
|
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(
|
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
|
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.
|
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
|
-
|
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
|
-
|
91
|
+
bvs,
|
92
|
+
)
|
88
93
|
end
|
89
94
|
|
90
95
|
def substitute_values(values) # :nodoc:
|
91
|
-
|
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 |
|
97
|
-
|
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
|
304
|
-
#
|
305
|
-
#
|
306
|
-
#
|
307
|
-
#
|
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 +
|
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 =
|
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)
|