postgres模式的数据库清理

paw*_*318 1 postgresql rspec ruby-on-rails devise database-cleaner

gem devisegem apartment我正在使用以创建每个色器件的用户帐户是不同的模式.

公寓的文档该问题的建议建议使用Rack中间件在租户之间切换.在那种情况下,我不可能(据我所知),因为我有用户依赖而不是请求依赖.

除了我的RSpec测试之外,所有工作都很棒.问题是每个测试数据库都没有正确清理后(它不会删除新创建的用户的模式).如果我运行一Faker::Internet.first_name小组它们,但是如果我运行多次而不是生成已经采用的用户名(这是无效的),则所有测试都会通过.

所以这就是我做到的:

应用程序/控制器/ application_controller.rb

def scope_tenant
  Apartment::Database.switch(current_user.username)
end
Run Code Online (Sandbox Code Playgroud)

app/controllers/albums_controller.rb(专辑模型belong_to :user)

class AlbumsController < ApplicationController
  before_action :authenticate_user! # devise magic
  before_action :scope_tenant
Run Code Online (Sandbox Code Playgroud)

应用程序/模型/ user.rb

after_create :create_schema

private

  def create_schema    
    Apartment::Database.create(self.username)
  end  
Run Code Online (Sandbox Code Playgroud)

这是我添加到我的规格中的内容:

规格/工厂/ user.rb

FactoryGirl.define do
  factory :user do
    username { Faker::Name.first_name }
    email { Faker::Internet.email("#{username}") }
    password "login_as will not use it anyway"
  end
end
Run Code Online (Sandbox Code Playgroud)

规格/支持/ auth_helpers.rb

Warden.test_mode!

def login_and_switch_schema(user)
 login_as(user)
 Apartment::Database.switch(user.username)    # for some reason `login_as()` didn't do that by itself
end
Run Code Online (Sandbox Code Playgroud)

规格/功能/ albums_spec.rb

feature "Album Pages" do

  given(:user) { create(:user) }
  given(:album) { create(:album) }

  around :each do
    login_and_switch_schema user
  end

  scenario...
Run Code Online (Sandbox Code Playgroud)

因为我有一些测试js: true比我有:

规格/支持/ database_cleaner.rb

RSpec.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

end
Run Code Online (Sandbox Code Playgroud)

所有来源的当前提交都可以在我的github上找到.

那么......主要的问题是:如何在测试后为每个用户清理数据库创建的模式?我也会感谢任何其他评论.提前感谢您的帮助.

bra*_*rad 5

这不是以任何方式特定于Apartment,它与DatabaseCleaner如何清理db有关.使用事务时,也将回滚在该事务中创建的任何模式.但不幸的是,您需要截断功能规范,因为事务不起作用(不要尝试共享连接'解决方案',它会因竞争条件而导致随机故障).因此,对于您的功能规范,您需要一种方法来确保删除所创建的任何模式,因为截断只会截断表并且不会清除模式.

我建议隔离专门测试多租户行为的功能规范,以确保它按照您希望的方式工作,并手动清理这些规范中创建的任何模式.然后,对于其余的功能规范,假设您在一个租户中进行测试,或者在您的情况下测试一个用户.

我们在测试套件中执行此操作,其中新Company模型创建新模型tenant.因此,对于多个租户,我们测试该行为,然后对于我们在1个公司内运行的其余功能,我们不再需要担心清理,我们可以截断该1个租户中的表.除非您有截断,否则截断将始终截断当前租户中的表excluded_models.

这有帮助吗?