Permalink
Browse files

Optimistic locking: gracefully handle nil versions, treat as zero. Cl…

…oses #5908.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4958 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent 9b18c1c commit 528618a91082748133488fefbf5f57cf8b96ed75 @jeremy jeremy committed Sep 4, 2006
View
@@ -1,5 +1,7 @@
*SVN*
+* Optimistic locking: gracefully handle nil versions, treat as zero. #5908 [Tom Ward]
+
* validates_confirmation_of only kicks in when the attribute, rather than its confirmation, is present. #785 [z@wzph.com]
* to_xml: the :methods option works on arrays of records. #5845 [Josh Starcher]
@@ -30,6 +30,8 @@ def self.included(base) #:nodoc:
base.lock_optimistically = true
base.alias_method_chain :update, :lock
+ base.alias_method_chain :attributes_from_column_definition, :lock
+
class << base
alias_method :locking_column=, :set_locking_column
end
@@ -39,6 +41,21 @@ def locking_enabled? #:nodoc:
lock_optimistically && respond_to?(self.class.locking_column)
end
+ def attributes_from_column_definition_with_lock
+ result = attributes_from_column_definition_without_lock
+
+ # If the locking column has no default value set,
+ # start the lock version at zero. Note we can't use
+ # locking_enabled? at this point as @attributes may
+ # not have been initialized yet
+
+ if lock_optimistically && result.include?(self.class.locking_column)
+ result[self.class.locking_column] ||= 0
+ end
+
+ return result
+ end
+
def update_with_lock #:nodoc:
return update_without_lock unless locking_enabled?
@@ -49,4 +49,12 @@ def create_table(*args, &block)
t.column :sink_id, :integer, :null => false
end
add_index :edges, [:source_id, :sink_id], :unique => true, :name => 'unique_edge_index'
+
+ create_table :lock_without_defaults, :force => true do |t|
+ t.column :lock_version, :integer
+ end
+
+ create_table :lock_with_custom_column_without_defaults, :force => true do |t|
+ t.column :custom_lock_version, :integer
+ end
end
@@ -2,6 +2,12 @@
require 'fixtures/person'
require 'fixtures/legacy_thing'
+class LockWithoutDefault < ActiveRecord::Base; end
+
+class LockWithCustomColumnWithoutDefault < ActiveRecord::Base
+ set_locking_column :custom_lock_version
+end
+
class OptimisticLockingTest < Test::Unit::TestCase
fixtures :people, :legacy_things
@@ -56,6 +62,16 @@ def test_lock_column_is_mass_assignable
assert_equal 1, p1.lock_version
assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
end
+
+ def test_lock_without_default_sets_version_to_zero
+ t1 = LockWithoutDefault.new
+ assert_equal 0, t1.lock_version
+ end
+
+ def test_lock_with_custom_column_without_default_sets_version_to_zero
+ t1 = LockWithCustomColumnWithoutDefault.new
+ assert_equal 0, t1.custom_lock_version
+ end
end

0 comments on commit 528618a

Please sign in to comment.