rails/activerecord/test
Godfrey Chan 7386ffc781 Restore ActiveRecord states after a rollback for models w/o callbacks
This fixes a regression (#13744) that was caused by 67d8bb9.

In 67d8bb9, we introduced lazy rollback for records, such that the
record's internal states and attributes are not restored immediately
after a transaction rollback, but deferred until they are first
accessed.

This optimization is only performed when the model does not have any
transactional callbacks (e.g. `after_commit` and `after_create`).

Unfortunately, the models used to test the affected codepaths all
comes with some sort of transactional callbacks. Therefore this
codepath remains largely untested until now and as a result there are
a few issues in the implementation that remains hidden until now.

First, the `sync_with_transaction_state` (or more accurately,
`update_attributes_from_transaction_state`) would perform the
synchronization prematurely before a transaction is finalized (i.e.
comitted or rolled back). As a result, when the actuall rollback
happens, the record will incorrectly assumes that its internal states
match the transaction state, and neglect to perform the restore.

Second, `update_attributes_from_transaction_state` calls `committed!`
in some cases. This in turns checks for the `destroyed?` state which
also requires synchronization with the transaction stae, which causes
an infnite recurrsion.

This fix works by deferring the synchronization until the transaction
has been finalized (addressing the first point), and also unrolled
the `committed!` and `rolledback!` logic in-place (addressing the
second point).

It should be noted that the primary purpose of the `committed!` and
`rolledback!` methods are to trigger the relevant transactional
callbacks. Since this code path is only entered when there are no
transactional callbacks on the model, this shouldn't be necessary. By
unrolling the method calls, the intention here (to restore the states
when necessary) becomes more clear.
2014-01-18 11:16:52 -08:00
..
active_record/connection_adapters Ensure disconnecting or reconnecting resets the transaction state 2012-09-15 00:03:04 +01:00
assets
cases Restore ActiveRecord states after a rollback for models w/o callbacks 2014-01-18 11:16:52 -08:00
fixtures Extend ActiveRecord::Base#cache_key to take an optional list of timestamp attributes of which the highest will be used. 2013-11-02 16:05:19 -07:00
migrations activerecord: Initialize Migration with version from MigrationProxy. 2014-01-06 10:46:35 -05:00
models Make AR::Base#touch fire the after_commit and after_rollback callbacks 2014-01-16 09:05:59 -02:00
schema Don't try to get the subclass if the inheritance column doesn't exist 2014-01-14 18:53:45 +05:30
support Deprecate use of string in establish_connection as connection lookup 2013-12-24 10:18:54 +01:00
.gitignore
config.example.yml Simulated & actual (manual/skipped) PostgreSQL auto-reconnection tests. 2012-07-16 09:55:20 -07:00
config.rb