Hello all,
I'm struggling to understand why an `after_create_commit` is executed in an
example although `use_transactional_fixtures` is set to `true`.
I created a new Rails app to isolate/test this behavior:
ruby 3.1.2
rails 7.0.4.3
rspec-rails 6.0.1
$ rails g scaffold article title content:text
$ rails g scaffold comment article:references content:text
Here are the models:
class Article < ApplicationRecord
has_many :comments, dependent: :destroy
after_create_commit -> { comments.create!(content: "First comment of
#{title}") }
end
class Comment < ApplicationRecord
belongs_to :article
end
Then I wrote the following test:
require 'rails_helper'
RSpec.describe Article, type: :model do
describe "create" do
subject { described_class.create!(title: "Hello", content: "world") }
it 'does not create a first comment' do
ActiveRecord::Base.logger = Logger.new(STDOUT)
expect { subject }.not_to change(Comment, :count).by(1)
end
end
end
I expect it NOT to create a comment because, from my understanding:
- The example is run within a transaction
- The after_create_commit is supposed to be run only after the transaction
is committed
- RSpec is supposed to rollback the transaction (once the example is over)
instead of committing it
- No commit, no after_create_commit. No after_create_commit, not comment
created.
To my surprise, the comment _is_ created. Here is the SQL log for the above
example:
```sql
D, [2023-04-26T15:51:25.707540 #346392] DEBUG -- : Comment Count (0.0ms)
SELECT COUNT(*) FROM "comments"
D, [2023-04-26T15:51:25.709992 #346392] DEBUG -- : TRANSACTION (0.0ms)
SAVEPOINT active_record_1
D, [2023-04-26T15:51:25.710339 #346392] DEBUG -- : Article Create (0.1ms)
INSERT INTO "articles" ("title", "content", "created_at", "updated_at")
VALUES (?, ?, ?, ?) [["title", "Hello"], ["content", "world"],
["created_at", "2023-04-26 13:51:25.709772"], ["updated_at", "2023-04-26
13:51:25.709772"]]
D, [2023-04-26T15:51:25.710480 #346392] DEBUG -- : TRANSACTION (0.0ms)
RELEASE SAVEPOINT active_record_1
D, [2023-04-26T15:51:25.713710 #346392] DEBUG -- : TRANSACTION (0.0ms)
SAVEPOINT active_record_1
D, [2023-04-26T15:51:25.713915 #346392] DEBUG -- : Comment Create (0.0ms)
INSERT INTO "comments" ("article_id", "content", "created_at",
"updated_at") VALUES (?, ?, ?, ?) [["article_id", 1], ["content", "First
comment of Hello"], ["created_at", "2023-04-26 13:51:25.713563"],
["updated_at", "2023-04-26 13:51:25.713563"]]
D, [2023-04-26T15:51:25.714024 #346392] DEBUG -- : TRANSACTION (0.0ms)
RELEASE SAVEPOINT active_record_1
D, [2023-04-26T15:51:25.714173 #346392] DEBUG -- : Comment Count (0.0ms)
SELECT COUNT(*) FROM "comments"
D, [2023-04-26T15:51:25.725359 #346392] DEBUG -- : TRANSACTION (0.1ms)
rollback transaction
```
It seems that the after_create_commit block is run after the savepoint,
which does not have the same meaning in my mind as after a commit. A
savepoint can still be rolled back so I'm not yet sure the data is
effectively persisted in the database while a commit cannot be rolled back
and the data _is_ persisted.
Am I missing something here? Any explanation/help will be much appreciated!
Thanks
--
You received this message because you are subscribed to the Google Groups
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/rspec/8ae6893e-92e6-471c-8243-3f519efc7dd2n%40googlegroups.com.