aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-06-17 09:41:06 -0600
committerSean Griffin <sean@thoughtbot.com>2014-06-17 09:41:06 -0600
commite30d701afe08acaa1c04da50791f07d4bb4efa83 (patch)
tree59278a753e92ff7a0e4ccc60ecdf87ce80d849e3 /activerecord
parente7a8fda0336fe733adbdd0bdb642a09327ef22f1 (diff)
downloadrails-e30d701afe08acaa1c04da50791f07d4bb4efa83.tar.gz
rails-e30d701afe08acaa1c04da50791f07d4bb4efa83.tar.bz2
rails-e30d701afe08acaa1c04da50791f07d4bb4efa83.zip
Don't mess with `column_defaults` when optimistic locking is enabled
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/base.rb4
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb33
-rw-r--r--activerecord/test/cases/locking_test.rb7
3 files changed, 32 insertions, 12 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 0b788ea1f9..662c99269e 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -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
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index 4528d8783c..0a764fb7ad 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -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
diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb
index c221430757..0c9dff2c25 100644
--- a/activerecord/test/cases/locking_test.rb
+++ b/activerecord/test/cases/locking_test.rb
@@ -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