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:
parent
e7a8fda033
commit
e30d701afe
3 changed files with 32 additions and 12 deletions
|
@ -308,10 +308,10 @@ module ActiveRecord #:nodoc:
|
|||
include Integration
|
||||
include Validations
|
||||
include CounterCache
|
||||
include Locking::Optimistic
|
||||
include Locking::Pessimistic
|
||||
include Attributes
|
||||
include AttributeDecorators
|
||||
include Locking::Optimistic
|
||||
include Locking::Pessimistic
|
||||
include AttributeMethods
|
||||
include Callbacks
|
||||
include Timestamp
|
||||
|
|
|
@ -53,6 +53,11 @@ module ActiveRecord
|
|||
included do
|
||||
class_attribute :lock_optimistically, instance_writer: false
|
||||
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
|
||||
|
||||
def locking_enabled? #:nodoc:
|
||||
|
@ -141,7 +146,7 @@ module ActiveRecord
|
|||
|
||||
# Set the column to use for optimistic locking. Defaults to +lock_version+.
|
||||
def locking_column=(value)
|
||||
@column_defaults = nil
|
||||
clear_caches_calculated_from_columns
|
||||
@locking_column = value.to_s
|
||||
end
|
||||
|
||||
|
@ -162,18 +167,26 @@ module ActiveRecord
|
|||
counters = counters.merge(locking_column => 1) if locking_enabled?
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def column_defaults
|
||||
@column_defaults ||= begin
|
||||
defaults = super
|
||||
class LockingType < SimpleDelegator
|
||||
def type_cast_from_database(value)
|
||||
# `nil` *should* be changed to 0
|
||||
super.to_i
|
||||
end
|
||||
|
||||
if defaults.key?(locking_column) && lock_optimistically
|
||||
defaults[locking_column] ||= 0
|
||||
end
|
||||
def changed?(old_value, *)
|
||||
# Ensure we save if the default was `nil`
|
||||
super || old_value == 0
|
||||
end
|
||||
|
||||
defaults
|
||||
end
|
||||
end
|
||||
def init_with(coder)
|
||||
__setobj__(coder['subtype'])
|
||||
end
|
||||
|
||||
def encode_with(coder)
|
||||
coder['subtype'] = __getobj__
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -272,6 +272,13 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|||
assert p.treasures.empty?
|
||||
assert RichPerson.connection.select_all("SELECT * FROM peoples_treasures WHERE rich_person_id = 1").empty?
|
||||
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
|
||||
|
||||
class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
|
||||
|
|
Loading…
Reference in a new issue