Optimistic locking: gracefully handle nil versions, treat as zero. Closes #5908.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4958 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jeremy Kemper 2006-09-04 00:02:38 +00:00
parent 9b18c1cb57
commit 528618a910
4 changed files with 43 additions and 0 deletions

View File

@ -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]

View File

@ -30,6 +30,8 @@ module ActiveRecord
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 @@ module ActiveRecord
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?

View File

@ -49,4 +49,12 @@ ActiveRecord::Schema.define do
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

View File

@ -2,6 +2,12 @@ require 'abstract_unit'
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 @@ class OptimisticLockingTest < Test::Unit::TestCase
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