Accidental replacement of main DB model connections in multi-database env

Open
#97 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
42/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
rails, ruby
Domain
databases, testing

Research direction

Start with the full reproduction in the linked gist and trace DatabaseCleaner::Cleaners through the ActiveRecord setup, especially the :bar truncation strategy. Verify the case where Bar is defined after cleaner.clean; done means Foo.connection still points to its main database and Foo.connection.tables remains ["foos"].

Written by the indexing model from the issue text.

Description

Note: I will make a pull request that follows this issue.

Summary

When we use DatabaseCleaner for a multi-database environment, the connection for "main" models (i.e., models inheriting the connection pool from ActiveRecord::Base) gets replaced with the connection for non-main models.

Reproduction

For the full reproduction code, see https://gist.github.com/kaorukobo/8dd0e5ef6c8662cc5de88aceea5043a1

setcwd_to_tmpdir
load_gems
create_config_database_yml
setup_activerecord

# defines Foo model, which use the connection pool from ApplicationRecord.
def define_foo_model
  eval(<<~RUBY, TOPLEVEL_BINDING)
    class Foo < ApplicationRecord
      connection.exec_query "CREATE TABLE foos (id INTEGER PRIMARY KEY)"
      reset_column_information
    end
  RUBY
end

# defines Bar model, which connects to alternate DB to be cleaned by DatabaseCleaner.
def define_bar_model
  eval(<<~RUBY, TOPLEVEL_BINDING)
    class Bar < ApplicationRecord
      establish_connection :bar
      connection.exec_query "CREATE TABLE bars (id INTEGER PRIMARY KEY)"
      reset_column_information
    end
  RUBY
end

RSpec.describe do
  it "works" do
    define_foo_model

    expect(Foo.connection.tables).to eq(["foos"])

    cleaner = DatabaseCleaner::Cleaners.new
    cleaner[:active_record, :db => :bar].strategy = :truncation
    cleaner.clean

    # define Bar model after `cleaner.clean`
    define_bar_model

    # Foo.connection gets replaced with Bar's connection!
    #
    # expected: ["foos"]
    #      got: ["bars"]
    expect(Foo.connection.tables).to eq(["foos"])
  end
end
Dominant language
Ruby
Stars
76
Forks
76
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from DatabaseCleaner/database_cleaner-active_record

All issues in DatabaseCleaner/database_cleaner-active_record

Similar issues

More Ruby issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.