DatabaseCleaner / database_cleaner-active_record

Strategies for cleaning databases using ActiveRecord. Can be used to ensure a clean state for testing.
MIT License
64 stars 63 forks source link

After rollback, the ActiveRecord query cache returns objects from previous test #29

Closed mgarrick closed 1 year ago

mgarrick commented 11 years ago

We're using Rails 3.2.11, Cucumber, and Database Cleaner with transaction cleaning. The basic problem we're seeing is that ActiveRecord is returning objects from previous tests because the query cache is not cleared. Here's an example:

Test 1:

User.create(:email => 'some@where.com')

Test 2:

# The Rails log indicates that this hits the ActiveRecord
# query cache, returning the User created in Test 1.
User.find_by_email('some@where.com')

We're currently getting around this by using a Cucumber After hook, like so:

After do |scenario|
  ActiveRecord::Base.connection.clear_query_cache
end

My expectation is that either Database Cleaner or Rails should handle clearing the query cache at the end of each scenario/rollback.

This may not be a Database Cleaner issue (I think it depends on if Rails is responsible for clearing the query cache on rollback, or if calling code is).

mikz commented 10 years ago

Also hit this issue. It should be in the documentation at least.

DatabaseCleaner uses ActiveRecord to clean the tables, so it can also clear query cache I would say. Or is it rails issue? I hit this on rails 4.1.

pwim commented 9 years ago

Looking at the current Rails (4.2.4), this issue seems to be resolved for the transaction strategy, as per the referenced issue.

However, I encountered a similar issue using the truncation strategy (and the deletion strategy also seems to suffer from it). The query cache is only reset when certain methods are invoked, (:insert, :update, :delete, :rollback_to_savepoint, :rollback_db_transaction as of Rails 4.2.4). As the deletion and truncation strategy directly execute statements on the database, the query cache isn't reset.

Resolving this should be as simple as adding connection.clear_query_cache to the clean method.

etagwerker commented 1 year ago

Closing this issue due to inactivity.