aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/transactions_test.rb
diff options
context:
space:
mode:
authorEugene Kenny <elkenny@gmail.com>2017-03-13 02:01:18 +0000
committerEugene Kenny <elkenny@gmail.com>2017-07-09 01:26:20 +0100
commitb19c4eff47d912ee3a038a6e0653eea7df5b67b8 (patch)
tree7412e9d3c3e019d6f6e93ff1e328836412ecca65 /activerecord/test/cases/transactions_test.rb
parent72e1c4229ab0af6a76c1635adff76fc02fa7fe71 (diff)
downloadrails-b19c4eff47d912ee3a038a6e0653eea7df5b67b8.tar.gz
rails-b19c4eff47d912ee3a038a6e0653eea7df5b67b8.tar.bz2
rails-b19c4eff47d912ee3a038a6e0653eea7df5b67b8.zip
Sync transaction state when accessing primary key
If a record is modified inside a transaction, it must check the outcome of that transaction before accessing any state which would no longer be valid if it was rolled back. For example, consider a new record that was saved inside a transaction which was later rolled back: it should be restored to its previous state so that saving it again inserts a new row into the database instead of trying to update a row that no longer exists. The `id` and `id=` methods defined on the PrimaryKey module implement this correctly, but when a model uses a custom primary key, the reader and writer methods for that attribute must check the transaction state too. The `read_attribute` and `write_attribute` methods also need to check the transaction state when accessing the primary key.
Diffstat (limited to 'activerecord/test/cases/transactions_test.rb')
-rw-r--r--activerecord/test/cases/transactions_test.rb52
1 files changed, 49 insertions, 3 deletions
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 76a997ba8b..a5348e2825 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -684,7 +684,7 @@ class TransactionTest < ActiveRecord::TestCase
raise ActiveRecord::Rollback
end
- assert_nil movie.id
+ assert_nil movie.movieid
end
def test_assign_id_after_rollback
@@ -707,8 +707,54 @@ class TransactionTest < ActiveRecord::TestCase
raise ActiveRecord::Rollback
end
- movie.id = nil
- assert_nil movie.id
+ movie.movieid = nil
+ assert_nil movie.movieid
+ end
+
+ def test_read_attribute_after_rollback
+ topic = Topic.new
+
+ Topic.transaction do
+ topic.save!
+ raise ActiveRecord::Rollback
+ end
+
+ assert_nil topic.read_attribute(:id)
+ end
+
+ def test_read_attribute_with_custom_primary_key_after_rollback
+ movie = Movie.new(name: "foo")
+
+ Movie.transaction do
+ movie.save!
+ raise ActiveRecord::Rollback
+ end
+
+ assert_nil movie.read_attribute(:movieid)
+ end
+
+ def test_write_attribute_after_rollback
+ topic = Topic.create!
+
+ Topic.transaction do
+ topic.save!
+ raise ActiveRecord::Rollback
+ end
+
+ topic.write_attribute(:id, nil)
+ assert_nil topic.id
+ end
+
+ def test_write_attribute_with_custom_primary_key_after_rollback
+ movie = Movie.create!(name: "foo")
+
+ Movie.transaction do
+ movie.save!
+ raise ActiveRecord::Rollback
+ end
+
+ movie.write_attribute(:movieid, nil)
+ assert_nil movie.movieid
end
def test_rollback_of_frozen_records