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

[psql] not cleaning with same database, different schemas #18

Open junhanamaki opened 9 years ago

junhanamaki commented 9 years ago

Hi. I've been having trouble with making database cleaner work when trying to delete data from different psql schemas, but in the same database.

database.yml:

test: &test
  adapter: postgresql
  database: test_project
  host: localhost
  port: 6432
  user: postgres

test_non_public:
  <<: *test
  schema_search_path: non_public

What I did in spec_helper:

config.before(:suite) do
  DatabaseCleaner.clean_with :deletion
  DatabaseCleaner[:active_record, connection: :test_non_public].clean_with :deletion
end

From what I understand it happens because of this code:

      def lookup_from_connection_pool
        if ::ActiveRecord::Base.respond_to?(:descendants)
          database_name = connection_hash["database"] || connection_hash[:database]
          models        = ::ActiveRecord::Base.descendants
          models.detect { |m| m.connection_pool.spec.config[:database] == database_name }
        end
      end

This method is invoked from connection_class, and because both connection "test" and "test_non_public" are configured to connect to the same database it ends up returning a model with an incorrect connection. This could be solved (I think) by adding one more condition, so that besides checking for the database_name it also checks for the schema_search_path.

While writing this issue I ended up editing the code as follows and it worked:

      def lookup_from_connection_pool
        if ::ActiveRecord::Base.respond_to?(:descendants)
          database_name      = connection_hash["database"] || connection_hash[:database]
          schema_search_path = connection_hash["schema_search_path"] || connection_hash[:schema_search_path]
          models             = ::ActiveRecord::Base.descendants
          models.detect do |m|
            m.connection_pool.spec.config[:database] == database_name &&
            m.connection_pool.spec.config[:schema_search_path] == schema_search_path
          end
        end
      end

Does it look like a good fix? If not how should I approach this problem so that I can solve this issue?

Thanks

geofflane commented 9 years ago

:+1: I'm seeing this as well with a similar configuration of connecting to MySQL but with multiple databases on the same server. A "normal" model that should connect to the default configured under the "test" key is switching to the non-default "other_test" connection.

sbonami commented 7 years ago

Bump? I'm seeing this as well

mowat27 commented 1 year ago

Is there any chance of this being prioritised please? My app has a number of extra schemas specified in schema_search_path and database cleaner cleans them properly in database_cleaner (1.99.0) but not the modern configuration of database_cleaner-active_record (2.1.0) + database_cleaner-core (~> 2.0.0) (from Gemfile.lock)