Clear locking column on #dup

When duplicating records, we usually want to create a new record and
don't want to keep the original lock_version. Just like timestamp
columns are not copied.

Co-authored-by: Seonggi Yang <seonggi.yang@gmail.com>
Co-authored-by: Ryohei UEDA <ueda@anipos.co.jp>
This commit is contained in:
Shouichi Kamiya 2022-10-14 16:06:54 +09:00
parent b75fc7b994
commit 13d3fc9d32
4 changed files with 48 additions and 2 deletions

@ -1,3 +1,16 @@
* Clear locking column on #dup
This change fixes not to duplicate locking_column like id and timestamps.
```
car = Car.create!
car.touch
car.lock_version #=> 1
car.dup.lock_version #=> 0
```
*Shouichi Kamiya*, *Seonggi Yang*, *Ryohei UEDA*
* Allow configuring columns list to be used in SQL queries issued by an `ActiveRecord::Base` object
It is now possible to configure columns list that will be used to build an SQL query clauses when

@ -517,7 +517,8 @@ def init_with_attributes(attributes, new_record = false) # :nodoc:
# only, not its associations. The extent of a "deep" copy is application
# specific and is therefore left to the application to implement according
# to its need.
# The dup method does not preserve the timestamps (created|updated)_(at|on).
# The dup method does not preserve the timestamps (created|updated)_(at|on)
# and locking column.
##
def initialize_dup(other) # :nodoc:

@ -69,6 +69,11 @@ def increment!(*, **) # :nodoc:
end
end
def initialize_dup(other) # :nodoc:
super
_clear_locking_column if locking_enabled?
end
private
def _create_record(attribute_names = self.attribute_names)
if locking_enabled?
@ -142,6 +147,11 @@ def _lock_value_for_database(locking_column)
end
end
def _clear_locking_column
self[self.class.locking_column] = nil
clear_attribute_change(self.class.locking_column)
end
module ClassMethods
DEFAULT_LOCKING_COLUMN = "lock_version"

@ -4,10 +4,11 @@
require "models/reply"
require "models/topic"
require "models/movie"
require "models/car"
module ActiveRecord
class DupTest < ActiveRecord::TestCase
fixtures :topics
fixtures :topics, :cars
def test_dup
assert_not_predicate Topic.new.freeze.dup, :frozen?
@ -118,6 +119,27 @@ def test_dup_timestamps_are_cleared
assert_not_nil new_topic.created_at
end
def test_dup_locking_column_is_cleared
car = Car.first
car.touch
assert_not_equal 0, car.lock_version
car.lock_version = 1000
new_car = car.dup
assert_equal 0, new_car.lock_version
end
def test_dup_locking_column_is_not_dirty
car = Car.first
car.touch
assert_not_equal 0, car.lock_version
car.lock_version += 1
new_car = car.dup
assert_not_predicate new_car, :lock_version_changed?
end
def test_dup_after_initialize_callbacks
topic = Topic.new
assert Topic.after_initialize_called