From 8f9a7ca854ffda26c5ce9aed2aec10bf155d0463 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Mon, 1 Aug 2016 18:34:17 +0300 Subject: Revert the revert of Optimistic Locking --- config/initializers/ar_monkey_patch.rb | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 config/initializers/ar_monkey_patch.rb (limited to 'config/initializers') diff --git a/config/initializers/ar_monkey_patch.rb b/config/initializers/ar_monkey_patch.rb new file mode 100644 index 00000000000..0da584626ee --- /dev/null +++ b/config/initializers/ar_monkey_patch.rb @@ -0,0 +1,57 @@ +# rubocop:disable Lint/RescueException + +# This patch fixes https://github.com/rails/rails/issues/26024 +# TODO: Remove it when it's no longer necessary + +module ActiveRecord + module Locking + module Optimistic + # We overwrite this method because we don't want to have default value + # for newly created records + def _create_record(attribute_names = self.attribute_names, *) # :nodoc: + super + end + + def _update_record(attribute_names = self.attribute_names) #:nodoc: + return super unless locking_enabled? + return 0 if attribute_names.empty? + + lock_col = self.class.locking_column + + previous_lock_value = send(lock_col).to_i + + # This line is added as a patch + previous_lock_value = nil if previous_lock_value == '0' || previous_lock_value == 0 + + increment_lock + + attribute_names += [lock_col] + attribute_names.uniq! + + begin + relation = self.class.unscoped + + affected_rows = relation.where( + self.class.primary_key => id, + lock_col => previous_lock_value, + ).update_all( + attributes_for_update(attribute_names).map do |name| + [name, _read_attribute(name)] + end.to_h + ) + + unless affected_rows == 1 + raise ActiveRecord::StaleObjectError.new(self, "update") + end + + affected_rows + + # If something went wrong, revert the version. + rescue Exception + send(lock_col + '=', previous_lock_value) + raise + end + end + end + end +end -- cgit v1.2.1