diff options
author | wycats <wycats@gmail.com> | 2010-04-30 11:17:58 -0700 |
---|---|---|
committer | wycats <wycats@gmail.com> | 2010-04-30 11:17:58 -0700 |
commit | 0fe8827bf384cb99ab757236555c7af18793d515 (patch) | |
tree | a7ac2143c78964cad8ee87d9ff8a1c52abf61249 /activerecord/lib/active_record/locking/optimistic.rb | |
parent | 91963e9e33eb5a28297323f1346aeb8b643e9d65 (diff) | |
parent | 6b559474fb7fae0160860fc62752da347af032b2 (diff) | |
download | rails-0fe8827bf384cb99ab757236555c7af18793d515.tar.gz rails-0fe8827bf384cb99ab757236555c7af18793d515.tar.bz2 rails-0fe8827bf384cb99ab757236555c7af18793d515.zip |
Merge branch 'master' of github.com:rails/rails
Diffstat (limited to 'activerecord/lib/active_record/locking/optimistic.rb')
-rw-r--r-- | activerecord/lib/active_record/locking/optimistic.rb | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb index 9044ca418b..60ad23f38c 100644 --- a/activerecord/lib/active_record/locking/optimistic.rb +++ b/activerecord/lib/active_record/locking/optimistic.rb @@ -23,6 +23,16 @@ module ActiveRecord # p2.first_name = "should fail" # p2.save # Raises a ActiveRecord::StaleObjectError # + # Optimistic locking will also check for stale data when objects are destroyed. Example: + # + # p1 = Person.find(1) + # p2 = Person.find(1) + # + # p1.first_name = "Michael" + # p1.save + # + # p2.destroy # Raises a ActiveRecord::StaleObjectError + # # You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, # or otherwise apply the business logic needed to resolve the conflict. # @@ -39,6 +49,7 @@ module ActiveRecord self.lock_optimistically = true alias_method_chain :update, :lock + alias_method_chain :destroy, :lock alias_method_chain :attributes_from_column_definition, :lock class << self @@ -88,7 +99,7 @@ module ActiveRecord unless affected_rows == 1 - raise ActiveRecord::StaleObjectError, "Attempted to update a stale object" + raise ActiveRecord::StaleObjectError, "Attempted to update a stale object: #{self.class.name}" end affected_rows @@ -100,6 +111,28 @@ module ActiveRecord end end + def destroy_with_lock #:nodoc: + return destroy_without_lock unless locking_enabled? + + unless new_record? + lock_col = self.class.locking_column + previous_value = send(lock_col).to_i + + affected_rows = connection.delete( + "DELETE FROM #{self.class.quoted_table_name} " + + "WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quoted_id} " + + "AND #{self.class.quoted_locking_column} = #{quote_value(previous_value)}", + "#{self.class.name} Destroy" + ) + + unless affected_rows == 1 + raise ActiveRecord::StaleObjectError, "Attempted to delete a stale object: #{self.class.name}" + end + end + + freeze + end + module ClassMethods DEFAULT_LOCKING_COLUMN = 'lock_version' |