如何截断不同于 Public (database_cleaner) 的架构中的所有数据
How to truncation all data in a schema different from the Public (database_cleaner)
在我的项目中我使用了数据库多租户'apartment' gem.
config/initializers/apartment.rb
Apartment.configure do |config|
config.excluded_models = %w{ User Company }
end
为了清理它测试的数据库,我使用 'database_cleaner' gem
spec/rails_helper.rb
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do |example|
DatabaseCleaner.strategy= example.metadata[:js] ? :truncation : :transaction
DatabaseCleaner.start
Apartment::Tenant.switch!('app')
end
config.after(:each) do
Apartment::Tenant.switch!
DatabaseCleaner.clean
end
end
在使用 Capybara 截断策略的 RSpec 测试中,每次测试后仅清理 public 架构,其中只有用户和公司。
Before test start
Company.count#=> 0
其他方案未清零
Before test start
SomeModelInCompanySchema.count#=> 240
如何清除其他方案中的数据
我创建了自己的 class 来清除测试数据库
class CleanTestDatabase
TABLE_TO_EXCLUDE = ['spatial_ref_sys', 'schema_migrations']
CONNECTION = ActiveRecord::Base.connection
def self.clean(*tenants)
tenants.each{ |tenant| delete_all_in_tenant(tenant) }
end
def self.drop_all_schemas
schemas = ActiveRecord::Base.connection.select_values <<-SQL
SELECT
schema_name
FROM
information_schema.schemata
WHERE
schema_name NOT IN ('information_schema','public', 'postgis') AND
schema_name NOT LIKE 'pg%'
SQL
schemas.each { |schema| Apartment::Tenant.drop(schema) }
end
private
def self.delete_all_in_tenant(tenant)
CONNECTION.disable_referential_integrity do
tables_to_clean(tenant).each do |table|
delete_from(table) if table_has_new_rows?(table)
end
end
end
def self.tables_to_clean(tenant)
tables = CONNECTION.tables - TABLE_TO_EXCLUDE
tables.map{ |table| "#{tenant}.#{table}" }
end
def self.table_has_new_rows?(table_name)
CONNECTION.select_value("SELECT count(*) FROM #{table_name}").to_i > 0
end
def self.delete_from(table_name)
CONNECTION.execute("DELETE FROM #{table_name}")
end
end
spec/rails_helper.rb
config.before(:each) do
CleanTestDatabase.clean('public', 'app')
Apartment::Tenant.switch!('app')
end
在我的项目中我使用了数据库多租户'apartment' gem.
config/initializers/apartment.rb
Apartment.configure do |config|
config.excluded_models = %w{ User Company }
end
为了清理它测试的数据库,我使用 'database_cleaner' gem
spec/rails_helper.rb
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do |example|
DatabaseCleaner.strategy= example.metadata[:js] ? :truncation : :transaction
DatabaseCleaner.start
Apartment::Tenant.switch!('app')
end
config.after(:each) do
Apartment::Tenant.switch!
DatabaseCleaner.clean
end
end
在使用 Capybara 截断策略的 RSpec 测试中,每次测试后仅清理 public 架构,其中只有用户和公司。
Before test start
Company.count#=> 0
其他方案未清零
Before test start
SomeModelInCompanySchema.count#=> 240
如何清除其他方案中的数据
我创建了自己的 class 来清除测试数据库
class CleanTestDatabase
TABLE_TO_EXCLUDE = ['spatial_ref_sys', 'schema_migrations']
CONNECTION = ActiveRecord::Base.connection
def self.clean(*tenants)
tenants.each{ |tenant| delete_all_in_tenant(tenant) }
end
def self.drop_all_schemas
schemas = ActiveRecord::Base.connection.select_values <<-SQL
SELECT
schema_name
FROM
information_schema.schemata
WHERE
schema_name NOT IN ('information_schema','public', 'postgis') AND
schema_name NOT LIKE 'pg%'
SQL
schemas.each { |schema| Apartment::Tenant.drop(schema) }
end
private
def self.delete_all_in_tenant(tenant)
CONNECTION.disable_referential_integrity do
tables_to_clean(tenant).each do |table|
delete_from(table) if table_has_new_rows?(table)
end
end
end
def self.tables_to_clean(tenant)
tables = CONNECTION.tables - TABLE_TO_EXCLUDE
tables.map{ |table| "#{tenant}.#{table}" }
end
def self.table_has_new_rows?(table_name)
CONNECTION.select_value("SELECT count(*) FROM #{table_name}").to_i > 0
end
def self.delete_from(table_name)
CONNECTION.execute("DELETE FROM #{table_name}")
end
end
spec/rails_helper.rb
config.before(:each) do
CleanTestDatabase.clean('public', 'app')
Apartment::Tenant.switch!('app')
end