未验证 提交 af7d7b44 编写于 作者: K Kasper Timm Hansen 提交者: GitHub

Merge pull request #36276 from basecamp/previously-new-record

Introduce previously_new_record? on ActiveRecord::Base
* Add `ActiveRecord::Base#previously_new_record?` to show if a record was new before the last save.
*Tom Ward*
* Support descending order for `find_each`, `find_in_batches` and `in_batches`.
Batch processing methods allow you to work with the records in batches, greatly reducing memory consumption, but records are always batched from oldest id to newest.
......@@ -542,5 +546,4 @@
*Michael Duchemin*
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activerecord/CHANGELOG.md) for previous changes.
......@@ -412,6 +412,7 @@ def initialize_dup(other) # :nodoc:
_run_initialize_callbacks
@new_record = true
@previously_new_record = false
@destroyed = false
@_start_transaction_state = nil
@transaction_state = nil
......@@ -588,6 +589,7 @@ def to_ary
def init_internals
@primary_key = self.class.primary_key
@readonly = false
@previously_new_record = false
@destroyed = false
@marked_for_destruction = false
@destroyed_by_association = nil
......
......@@ -428,6 +428,14 @@ def new_record?
@new_record
end
# Returns true if this object was just created -- that is, prior to the last
# save, the object didn't exist in the database and new_record? would have
# returned true.
def previously_new_record?
sync_with_transaction_state if @transaction_state&.finalized?
@previously_new_record
end
# Returns true if this object has been destroyed, otherwise returns false.
def destroyed?
sync_with_transaction_state if @transaction_state&.finalized?
......@@ -811,6 +819,7 @@ def reload(options = nil)
@attributes = fresh_object.instance_variable_get(:@attributes)
@new_record = false
@previously_new_record = false
self
end
......@@ -914,6 +923,8 @@ def _update_record(attribute_names = self.attribute_names)
@_trigger_update_callback = affected_rows == 1
end
@previously_new_record = false
yield(self) if block_given?
affected_rows
......@@ -931,6 +942,7 @@ def _create_record(attribute_names = self.attribute_names)
self.id ||= new_id if @primary_key
@new_record = false
@previously_new_record = true
yield(self) if block_given?
......
......@@ -391,6 +391,7 @@ def remember_transaction_record_state
@_start_transaction_state ||= {
id: id,
new_record: @new_record,
previously_new_record: @previously_new_record,
destroyed: @destroyed,
attributes: @attributes,
frozen?: frozen?,
......@@ -423,6 +424,7 @@ def restore_transaction_record_state(force_restore_state = false)
if restore_state = @_start_transaction_state
if force_restore_state || restore_state[:level] <= 1
@new_record = restore_state[:new_record]
@previously_new_record = restore_state[:previously_new_record]
@destroyed = restore_state[:destroyed]
@attributes = restore_state[:attributes].map do |attr|
value = @attributes.fetch_value(attr.name)
......
......@@ -746,6 +746,12 @@ def test_new_record_returns_boolean
assert_equal true, Topic.find(1).persisted?
end
def test_previously_new_record_returns_boolean
assert_equal false, Topic.new.previously_new_record?
assert_equal true, Topic.create.previously_new_record?
assert_equal false, Topic.find(1).previously_new_record?
end
def test_dup
topic = Topic.find(1)
duped_topic = nil
......
......@@ -13,6 +13,7 @@ def test_persisted
assert topic.persisted?, "topic persisted"
assert cloned.persisted?, "topic persisted"
assert_not cloned.new_record?, "topic is not new"
assert_not cloned.previously_new_record?, "topic was not previously new"
end
def test_stays_frozen
......
......@@ -36,6 +36,13 @@ def test_dup_not_persisted
assert duped.new_record?, "topic is new"
end
def test_dup_not_previously_new_record
topic = Topic.first
duped = topic.dup
assert_not duped.previously_new_record?, "should not be a previously new record"
end
def test_dup_not_destroyed
topic = Topic.first
topic.destroy
......
......@@ -799,6 +799,18 @@ def test_dont_restore_new_record_in_subsequent_transaction
assert_not_predicate topic, :new_record?
end
def test_restore_previously_new_record_after_double_save
topic = Topic.create!
Topic.transaction do
topic.save!
topic.save!
raise ActiveRecord::Rollback
end
assert_predicate topic, :previously_new_record?
end
def test_restore_id_after_rollback
topic = Topic.new
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册