Hiya

Although this functionality is configured via `rspec-rails` config, its 
part of the thin wrapper for Rails functionality, so all RSpec does here is 
set the Rails setting.

That setting is supposed to wrap the entire test/spec in a transaction 
before rolling it back, and you can see the rollback at the end of the 
transaction, however you can see (presumedly) Rails automatically 
triggering the hook from the savepoint it presumedly created for you, thus 
creating the comments.

The end result of this entire thing should be nothing left in the database, 
but within the spec the transaction has yet to be rolled back, so the spec 
would fail.

Cheers
Jon


On Wednesday, 26 April 2023 at 16:31:06 UTC+1 younes...@gmail.com wrote:

> 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 rspec+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/276aa975-5d89-46eb-a8f7-fed446a9beedn%40googlegroups.com.

Reply via email to