aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/relation.rb')
-rw-r--r--activerecord/lib/active_record/relation.rb24
1 files changed, 14 insertions, 10 deletions
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index ad54d84665..03bce4f5b7 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -4,8 +4,6 @@ require 'arel/collectors/bind'
module ActiveRecord
# = Active Record Relation
class Relation
- JoinOperation = Struct.new(:relation, :join_class, :on)
-
MULTI_VALUE_METHODS = [:includes, :eager_load, :preload, :select, :group,
:order, :joins, :where, :having, :bind, :references,
:extending, :unscope]
@@ -81,22 +79,27 @@ module ActiveRecord
scope.unscope!(where: @klass.inheritance_column)
end
- um = scope.where(@klass.arel_table[@klass.primary_key].eq(id_was || id)).arel.compile_update(substitutes, @klass.primary_key)
+ relation = scope.where(@klass.primary_key => (id_was || id))
+ bvs = binds + relation.bind_values
+ um = relation
+ .arel
+ .compile_update(substitutes, @klass.primary_key)
+ reorder_bind_params(um.ast, bvs)
@klass.connection.update(
um,
'SQL',
- binds)
+ bvs,
+ )
end
def substitute_values(values) # :nodoc:
- substitutes = values.sort_by { |arel_attr,_| arel_attr.name }
- binds = substitutes.map do |arel_attr, value|
+ binds = values.map do |arel_attr, value|
[@klass.columns_hash[arel_attr.name], value]
end
- substitutes.each_with_index do |tuple, i|
- tuple[1] = @klass.connection.substitute_at(binds[i][0], i)
+ substitutes = values.each_with_index.map do |(arel_attr, _), i|
+ [arel_attr, @klass.connection.substitute_at(binds[i][0], i)]
end
[substitutes, binds]
@@ -305,7 +308,8 @@ module ActiveRecord
# Updates all records with details given if they match a set of conditions supplied, limits and order can
# also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the
# database. It does not instantiate the involved models and it does not trigger Active Record callbacks
- # or validations.
+ # or validations. Values passed to `update_all` will not go through ActiveRecord's type-casting behavior.
+ # It should receive only values that can be passed as-is to the SQL database.
#
# ==== Parameters
#
@@ -338,7 +342,7 @@ module ActiveRecord
stmt.wheres = arel.constraints
end
- bvs = bind_values + arel.bind_values
+ bvs = arel.bind_values + bind_values
@klass.connection.update stmt, 'SQL', bvs
end