From ea45d56d3d23e703b2866524202649e333fd7408 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono <kamipo@gmail.com> Date: Sun, 4 Mar 2018 00:39:53 +0900 Subject: Introduce `_delete_record` and use it for deleting a record --- .../lib/active_record/locking/optimistic.rb | 22 +++++++++------------- activerecord/lib/active_record/persistence.rb | 22 ++++++++++++++-------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb index c2f740a1e0..29735f5490 100644 --- a/activerecord/lib/active_record/locking/optimistic.rb +++ b/activerecord/lib/active_record/locking/optimistic.rb @@ -112,24 +112,20 @@ module ActiveRecord end def destroy_row - affected_rows = super + return super unless locking_enabled? - if locking_enabled? && affected_rows != 1 - raise ActiveRecord::StaleObjectError.new(self, "destroy") - end + locking_column = self.class.locking_column - affected_rows - end + affected_rows = self.class._delete_record( + self.class.primary_key => id_in_database, + locking_column => read_attribute_before_type_cast(locking_column) + ) - def relation_for_destroy - relation = super - - if locking_enabled? - locking_column = self.class.locking_column - relation = relation.where(locking_column => read_attribute_before_type_cast(locking_column)) + if affected_rows != 1 + raise ActiveRecord::StaleObjectError.new(self, "destroy") end - relation + affected_rows end module ClassMethods diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 610f11b66c..7b0b7a18e3 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -197,6 +197,16 @@ module ActiveRecord connection.update(um, "#{self} Update") end + def _delete_record(constraints) # :nodoc: + constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) } + + dm = Arel::DeleteManager.new + dm.from(arel_table) + dm.wheres = constraints + + connection.delete(dm, "#{self} Destroy") + end + private # Called by +instantiate+ to decide which class to use for a new # record instance. @@ -311,7 +321,7 @@ module ActiveRecord # callbacks or any <tt>:dependent</tt> association # options, use <tt>#destroy</tt>. def delete - _relation_for_itself.delete_all if persisted? + _delete_row if persisted? @destroyed = true freeze end @@ -690,15 +700,11 @@ module ActiveRecord end def destroy_row - relation_for_destroy.delete_all - end - - def relation_for_destroy - _relation_for_itself + _delete_row end - def _relation_for_itself - self.class.unscoped.where(self.class.primary_key => id_in_database) + def _delete_row + self.class._delete_record(self.class.primary_key => id_in_database) end def create_or_update(*args, &block) -- cgit v1.2.3