aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation.rb
diff options
context:
space:
mode:
authorJoe Van Dyk <joe@tanga.com>2015-03-21 01:16:13 -0700
committerJoe Van Dyk <joe@tanga.com>2015-03-21 01:16:13 -0700
commit4364211b7731f7b99b18c31456138c2e0f0c2aef (patch)
tree152ebf1c08c65d9767012ec1f361f5a871fbec1e /activerecord/lib/active_record/relation.rb
parent92a3c8dcdf174dab5e8759031b6bbe6cd891fe3c (diff)
downloadrails-4364211b7731f7b99b18c31456138c2e0f0c2aef.tar.gz
rails-4364211b7731f7b99b18c31456138c2e0f0c2aef.tar.bz2
rails-4364211b7731f7b99b18c31456138c2e0f0c2aef.zip
Fix documentation for find_or_create_by
The code in the comment fails on concurrent inserts if done inside a transaction. The fix is to force a savepoint to run so that if the database raises an unique violation exception. Otherwise, you'll get errors like: ``` (0.3ms) BEGIN Cart Load (0.5ms) SELECT "carts".* FROM "carts" WHERE "carts"."uuid" = '12345' LIMIT 1 # Another process inserts a cart with uuid of '12345' right now SQL (4371.7ms) INSERT INTO "carts" ("created_at", "updated_at", "uuid") VALUES ('2015-03-21 01:05:07.833231', '2015-03-21 01:05:07.833231', '12345') RETURNING "id" [["created_at", Sat, 21 Mar 2015 01:05:07 PDT -07:00], ["updated_at", Sat, 21 Mar 2015 01:05:07 PDT -07:00], ["uuid", "12345"]] PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "carts_uuid_idx1" DETAIL: Key (uuid)=(12345) already exists. : INSERT INTO "carts" ("created_at", "updated_at", "uuid") VALUES ('2015-03-21 01:05:07.833231', '2015-03-21 01:05:07.833231', '12345') RETURNING "id" # Retrying the find Cart Load (0.8ms) SELECT "carts".* FROM "carts" WHERE "carts"."uuid" = '12345' LIMIT 1 PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block : SELECT "carts".* FROM "carts" WHERE "carts"."uuid" = '12345' LIMIT 1 (0.1ms) ROLLBACK ActiveRecord::StatementInvalid: PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block : SELECT "carts".* FROM "carts" WHERE "carts"."uuid" = '12345' LIMIT 1 ```
Diffstat (limited to 'activerecord/lib/active_record/relation.rb')
-rw-r--r--activerecord/lib/active_record/relation.rb4
1 files changed, 3 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 6bbec7c0c0..85648a7f8f 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -205,7 +205,9 @@ module ActiveRecord
# constraint an exception may be raised, just retry:
#
# begin
- # CreditAccount.find_or_create_by(user_id: user.id)
+ # CreditAccount.transaction(requires_new: true) do
+ # CreditAccount.find_or_create_by(user_id: user.id)
+ # end
# rescue ActiveRecord::RecordNotUnique
# retry
# end