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:
parent
9b18c1cb57
commit
528618a910
|
@ -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 @@ 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?
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue