1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Don't mess with column_defaults when optimistic locking is enabled

This commit is contained in:
Sean Griffin 2014-06-17 09:41:06 -06:00
parent e7a8fda033
commit e30d701afe
3 changed files with 32 additions and 12 deletions

View file

@ -308,10 +308,10 @@ module ActiveRecord #:nodoc:
include Integration include Integration
include Validations include Validations
include CounterCache include CounterCache
include Locking::Optimistic
include Locking::Pessimistic
include Attributes include Attributes
include AttributeDecorators include AttributeDecorators
include Locking::Optimistic
include Locking::Pessimistic
include AttributeMethods include AttributeMethods
include Callbacks include Callbacks
include Timestamp include Timestamp

View file

@ -53,6 +53,11 @@ module ActiveRecord
included do included do
class_attribute :lock_optimistically, instance_writer: false class_attribute :lock_optimistically, instance_writer: false
self.lock_optimistically = true self.lock_optimistically = true
is_lock_column = ->(name, _) { lock_optimistically && name == locking_column }
decorate_matching_attribute_types(is_lock_column, :_optimistic_locking) do |type|
LockingType.new(type)
end
end end
def locking_enabled? #:nodoc: def locking_enabled? #:nodoc:
@ -141,7 +146,7 @@ module ActiveRecord
# Set the column to use for optimistic locking. Defaults to +lock_version+. # Set the column to use for optimistic locking. Defaults to +lock_version+.
def locking_column=(value) def locking_column=(value)
@column_defaults = nil clear_caches_calculated_from_columns
@locking_column = value.to_s @locking_column = value.to_s
end end
@ -162,18 +167,26 @@ module ActiveRecord
counters = counters.merge(locking_column => 1) if locking_enabled? counters = counters.merge(locking_column => 1) if locking_enabled?
super super
end end
end
end
def column_defaults class LockingType < SimpleDelegator
@column_defaults ||= begin def type_cast_from_database(value)
defaults = super # `nil` *should* be changed to 0
super.to_i
end
if defaults.key?(locking_column) && lock_optimistically def changed?(old_value, *)
defaults[locking_column] ||= 0 # Ensure we save if the default was `nil`
end super || old_value == 0
end
defaults def init_with(coder)
end __setobj__(coder['subtype'])
end end
def encode_with(coder)
coder['subtype'] = __getobj__
end end
end end
end end

View file

@ -272,6 +272,13 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert p.treasures.empty? assert p.treasures.empty?
assert RichPerson.connection.select_all("SELECT * FROM peoples_treasures WHERE rich_person_id = 1").empty? assert RichPerson.connection.select_all("SELECT * FROM peoples_treasures WHERE rich_person_id = 1").empty?
end end
def test_yaml_dumping_with_lock_column
t1 = LockWithoutDefault.new
t2 = YAML.load(YAML.dump(t1))
assert_equal t1.attributes, t2.attributes
end
end end
class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase