rails/activerecord/test/schema
Kasper Timm Hansen cea392eb96
Polymorphic has_one touch: Reset association cache result after create transaction
In case of a polymorphic association there's no automatic inverse_of to assign the
inverse record. So to get the record there needs to be a query executed,
however, if the query fires within the transaction that's trying to create
the associated record, no record can be found. And worse, the nil result is cached
on the association so after the transaction commits the record can't be found.

That's what happens if touch is enabled on a polymorphic has_one association.

Consider a Comment with a commentable association that needs to be touched.

For `Comment.create(commentable: Post.new)`, the existing code essentially
does `commentable.send(:comment)` within the create transaction for the comment
and thus not finding the comment.

Now we're purposefully clearing the cache in case we've tried accessing
the association within the transaction and found no object.

Before:

```
kaspth-imac 2.6.3 ~/code/rails/activerecord master *= ARCONN=postgresql bin/test test/cases/associations/has_one_associations_test.rb -n /commit/
Using postgresql
Run options: -n /commit/ --seed 46022

D, [2019-07-19T03:30:37.864537 #96022] DEBUG -- :   Chef Load (0.2ms)  SELECT "chefs".* FROM "chefs" WHERE "chefs"."employable_id" = $1 AND "chefs"."employable_type" = $2 LIMIT $3  [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"], ["LIMIT", 1]]
D, [2019-07-19T03:30:37.865013 #96022] DEBUG -- :   Chef Create (0.2ms)  INSERT INTO "chefs" ("employable_id", "employable_type") VALUES ($1, $2) RETURNING "id"  [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"]]
D, [2019-07-19T03:30:37.865201 #96022] DEBUG -- :   TRANSACTION (0.1ms)  RELEASE SAVEPOINT active_record_1
D, [2019-07-19T03:30:37.874136 #96022] DEBUG -- :   TRANSACTION (0.1ms)  ROLLBACK
D, [2019-07-19T03:30:37.874323 #96022] DEBUG -- :   TRANSACTION (0.1ms)  ROLLBACK
F

Failure:
HasOneAssociationsTest#test_polymorphic_has_one_with_touch_option_on_create_wont_cache_assocation_so_fetching_after_transaction_commit_works [/Users/kaspth/code/rails/activerecord/test/cases/associations/has_one_associations_test.rb:716]:
--- expected
+++ actual
@@ -1 +1 @@
-#<Chef id: 1, employable_id: 1, employable_type: "DrinkDesignerWithPolymorphicTouchChef", department_id: nil, employable_list_type: nil, employable_list_id: nil>
+nil
```

After:

```
kaspth-imac 2.6.3 ~/code/rails/activerecord master *= ARCONN=postgresql bin/test test/cases/associations/has_one_associations_test.rb -n /commit/
Using postgresql
Run options: -n /commit/ --seed 46022

D, [2019-07-19T03:30:22.479387 #95973] DEBUG -- :   Chef Create (0.3ms)  INSERT INTO "chefs" ("employable_id", "employable_type") VALUES ($1, $2) RETURNING "id"  [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"]]
D, [2019-07-19T03:30:22.479574 #95973] DEBUG -- :   TRANSACTION (0.1ms)  RELEASE SAVEPOINT active_record_1
D, [2019-07-19T03:30:22.482051 #95973] DEBUG -- :   Chef Load (0.1ms)  SELECT "chefs".* FROM "chefs" WHERE "chefs"."employable_id" = $1 AND "chefs"."employable_type" = $2 LIMIT $3  [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"], ["LIMIT", 1]]
D, [2019-07-19T03:30:22.482317 #95973] DEBUG -- :   TRANSACTION (0.1ms)  ROLLBACK
D, [2019-07-19T03:30:22.482437 #95973] DEBUG -- :   TRANSACTION (0.1ms)  ROLLBACK
.

Finished in 0.088498s, 11.2997 runs/s, 22.5994 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
```

Notice the select now fires after the commit.
2019-07-31 05:59:23 +02:00
..
mysql2_specific_schema.rb MySQL: Fix schema dumping enum and set columns correctly 2019-07-05 18:42:41 +09:00
oracle_specific_schema.rb Use squiggly heredoc to strip odd indentation in the executed SQL 2018-11-22 19:43:53 +09:00
postgresql_specific_schema.rb Enable Layout/EmptyLinesAroundBlockBody to reduce review cost in the future 2018-07-12 21:29:48 +09:00
schema.rb Polymorphic has_one touch: Reset association cache result after create transaction 2019-07-31 05:59:23 +02:00
sqlite_specific_schema.rb add mysql and sqlite3 default test 2018-09-01 22:09:01 -04:00