From cd809b31761405a08c0791c0112a8dda300ed68b Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Mon, 15 Mar 2021 17:15:35 +0900 Subject: [PATCH] Improve `compile_update` and `compile_delete` To be used from `update_all` and `delete_all`. --- activerecord/lib/active_record/relation.rb | 26 ++++---------- activerecord/lib/arel/crud.rb | 40 ++++++++++------------ 2 files changed, 25 insertions(+), 41 deletions(-) diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 547297a822d..96e55ae6e66 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -469,14 +469,6 @@ module ActiveRecord return relation.update_all(updates) end - stmt = Arel::UpdateManager.new - stmt.table(arel.join_sources.empty? ? table : arel.source) - stmt.key = table[primary_key] - stmt.take(arel.limit) - stmt.offset(arel.offset) - stmt.order(*arel.orders) - stmt.wheres = arel.constraints - if updates.is_a?(Hash) if klass.locking_enabled? && !updates.key?(klass.locking_column) && @@ -484,12 +476,14 @@ module ActiveRecord attr = table[klass.locking_column] updates[attr.name] = _increment_attribute(attr) end - stmt.set _substitute_values(updates) + values = _substitute_values(updates) else - stmt.set Arel.sql(klass.sanitize_sql_for_assignment(updates, table.name)) + values = Arel.sql(klass.sanitize_sql_for_assignment(updates, table.name)) end - @klass.connection.update stmt, "#{@klass} Update All" + stmt = arel.compile_update(values, table[primary_key]) + + klass.connection.update(stmt, "#{klass} Update All") end def update(id = :all, attributes) # :nodoc: @@ -611,15 +605,9 @@ module ActiveRecord return relation.delete_all end - stmt = Arel::DeleteManager.new - stmt.from(arel.join_sources.empty? ? table : arel.source) - stmt.key = table[primary_key] - stmt.take(arel.limit) - stmt.offset(arel.offset) - stmt.order(*arel.orders) - stmt.wheres = arel.constraints + stmt = arel.compile_delete(table[primary_key]) - affected = @klass.connection.delete(stmt, "#{@klass} Destroy") + affected = klass.connection.delete(stmt, "#{klass} Destroy") reset affected diff --git a/activerecord/lib/arel/crud.rb b/activerecord/lib/arel/crud.rb index e8a563ca4ae..d7458b3315d 100644 --- a/activerecord/lib/arel/crud.rb +++ b/activerecord/lib/arel/crud.rb @@ -4,23 +4,6 @@ module Arel # :nodoc: all ### # FIXME hopefully we can remove this module Crud - def compile_update(values, pk) - um = UpdateManager.new - - if Nodes::SqlLiteral === values - relation = @ctx.from - else - relation = values.first.first.relation - end - um.key = pk - um.table relation - um.set values - um.take @ast.limit.expr if @ast.limit - um.order(*@ast.orders) - um.wheres = @ctx.wheres - um - end - def compile_insert(values) im = create_insert im.insert values @@ -31,11 +14,24 @@ module Arel # :nodoc: all InsertManager.new end - def compile_delete - dm = DeleteManager.new - dm.take @ast.limit.expr if @ast.limit - dm.wheres = @ctx.wheres - dm.from @ctx.froms + def compile_update(values, key = nil) + um = UpdateManager.new(source) + um.set(values) + um.take(limit) + um.offset(offset) + um.order(*orders) + um.wheres = constraints + um.key = key + um + end + + def compile_delete(key = nil) + dm = DeleteManager.new(source) + dm.take(limit) + dm.offset(offset) + dm.order(*orders) + dm.wheres = constraints + dm.key = key dm end end