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

Merge pull request #28914 from bogdanvlviv/fix-touch-with-optimistic-locking

Fix ActiveRecord::Persistence#touch with locking
This commit is contained in:
Rafael França 2017-06-20 18:48:51 -04:00 committed by GitHub
commit 0787727cd6
4 changed files with 33 additions and 3 deletions

View file

@ -1,3 +1,8 @@
* `ActiveRecord::Persistence#touch` does not work well when optimistic locking enabled and
`locking_column`, without default value, is null in the database.
*bogdanvlviv*
* Fix destroying existing object does not work well when optimistic locking enabled and * Fix destroying existing object does not work well when optimistic locking enabled and
`locking column` is null in the database. `locking column` is null in the database.

View file

@ -526,7 +526,7 @@ module ActiveRecord
if locking_enabled? if locking_enabled?
locking_column = self.class.locking_column locking_column = self.class.locking_column
scope = scope.where(locking_column => _read_attribute(locking_column)) scope = scope.where(locking_column => read_attribute_before_type_cast(locking_column))
changes[locking_column] = increment_lock changes[locking_column] = increment_lock
end end

View file

@ -244,10 +244,33 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_equal 0, t1.lock_version_before_type_cast assert_equal 0, t1.lock_version_before_type_cast
end end
def test_touch_existing_lock_without_default_should_work_with_null_in_the_database
ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
t1 = LockWithoutDefault.last
assert_equal 0, t1.lock_version
assert_nil t1.lock_version_before_type_cast
t1.touch
assert_equal 1, t1.lock_version
end
def test_touch_stale_object_with_lock_without_default
t1 = LockWithoutDefault.create!(title: "title1")
stale_object = LockWithoutDefault.find(t1.id)
t1.update!(title: "title2")
assert_raises(ActiveRecord::StaleObjectError) do
stale_object.touch
end
end
def test_lock_without_default_should_work_with_null_in_the_database def test_lock_without_default_should_work_with_null_in_the_database
ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')") ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
t1 = LockWithoutDefault.last t1 = LockWithoutDefault.last
t2 = LockWithoutDefault.last t2 = LockWithoutDefault.find(t1.id)
assert_equal 0, t1.lock_version assert_equal 0, t1.lock_version
assert_nil t1.lock_version_before_type_cast assert_nil t1.lock_version_before_type_cast
@ -304,7 +327,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults_cust(title) VALUES('title1')") ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults_cust(title) VALUES('title1')")
t1 = LockWithCustomColumnWithoutDefault.last t1 = LockWithCustomColumnWithoutDefault.last
t2 = LockWithCustomColumnWithoutDefault.last t2 = LockWithCustomColumnWithoutDefault.find(t1.id)
assert_equal 0, t1.custom_lock_version assert_equal 0, t1.custom_lock_version
assert_nil t1.custom_lock_version_before_type_cast assert_nil t1.custom_lock_version_before_type_cast

View file

@ -453,11 +453,13 @@ ActiveRecord::Schema.define do
create_table :lock_without_defaults, force: true do |t| create_table :lock_without_defaults, force: true do |t|
t.column :title, :string t.column :title, :string
t.column :lock_version, :integer t.column :lock_version, :integer
t.timestamps null: true
end end
create_table :lock_without_defaults_cust, force: true do |t| create_table :lock_without_defaults_cust, force: true do |t|
t.column :title, :string t.column :title, :string
t.column :custom_lock_version, :integer t.column :custom_lock_version, :integer
t.timestamps null: true
end end
create_table :magazines, force: true do |t| create_table :magazines, force: true do |t|