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 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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue