Хобрук: Ваш путь к мастерству в программировании

очистка базы данных для схем postgres

У меня есть gem devise и gem apartment, которые я использую для создания отдельных схем для каждой учетной записи пользователя устройства.

документ и рекомендации по этому вопросу предлагают использовать промежуточное ПО Rack для переключения между арендаторами. В этом случае это невозможно (насколько мне известно), поскольку у меня это зависит от пользователя, а не от запроса.

Все работает просто отлично, кроме моих тестов RSpec. Проблема в том, что после каждого теста база данных не очищается должным образом (не удаляет схему для нового созданного пользователя). Все тесты проходят, если я запускаю небольшой набор из них, но если я запускаю их больше, чем Faker::Internet.first_name, генерируются имена пользователей, которые уже были заняты (что недопустимо).

Итак, вот как я это сделал:

приложение/контроллеры/application_controller.rb

def scope_tenant
  Apartment::Database.switch(current_user.username)
end

app/controllers/albums_controller.rb (модель альбома belong_to :user)

class AlbumsController < ApplicationController
  before_action :authenticate_user! # devise magic
  before_action :scope_tenant

приложение/модель/user.rb

after_create :create_schema

private

  def create_schema    
    Apartment::Database.create(self.username)
  end  

Вот что я добавил в свои характеристики:

spec/factories/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

spec/support/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

spec/features/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...

Поскольку у меня есть несколько тестов с js: true, чем у меня есть:

spec/support/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

Текущая фиксация для всех источников доступна на моем github здесь.

Итак... главный вопрос: как очистить созданные базы данных схемы для каждого пользователя после теста? Я также буду признателен за любые другие комментарии. Заранее спасибо за помощь.


  • как насчет «удалить каскад схемы X»; ?? это должно удалить схему, тогда вы можете воссоздать пустую. теперь, когда я снова прочитал описание, может быть, схема означает что-то другое в рельсах? в postgres вы можете просто бросить его, и он исчезнет (если вы знаете имя). 20.05.2014

Ответы:


1

Это никоим образом не относится к квартире, это больше связано с тем, как DatabaseCleaner очищает вашу базу данных. При использовании транзакций любые схемы, созданные в этой транзакции, также будут отброшены. Однако, к сожалению, вам необходимо урезать спецификации функций, поскольку транзакции не работают (не пытайтесь использовать «решение» общего подключения, оно вызывает случайные сбои из-за состояния гонки). Итак, учитывая, что для ваших спецификаций функций вам нужен способ гарантировать удаление любых созданных схем, поскольку усечение только усекает таблицы и НЕ очищает схемы.

Я бы предложил изолировать ваши спецификации функций, которые специально проверяют поведение нескольких арендаторов, чтобы убедиться, что они работают так, как вы хотите, и вручную очистить все созданные схемы в этих спецификациях. Затем для остальных спецификаций функций предположим, что вы тестируете одного клиента или, в вашем случае, одного пользователя.

Мы делаем это в нашем наборе тестов, где новая модель Company создает новую модель tenant. Итак, мы тестируем это поведение для нескольких арендаторов, а затем для остальных наших функций мы работаем в одной компании, поэтому нам больше не нужно беспокоиться об очистке, и мы можем просто обрезать таблицы в этом 1 арендаторе. Truncate всегда усекает таблицы в текущем арендаторе, если у вас нет excluded_models.

Это помогает?

20.05.2014
  • много ! Спасибо. Я описал окончательное решение в другом ответе. (Я решил не разбивать спецификации функций, которые используют мультиарендность, поскольку для многих из них это важно. Например, у меня есть несколько тестов, которые проверяют, являются ли данные уникальными в области пользователя/арендатора) 20.05.2014

  • 2

    Еще один способ справиться с усеченными и многопользовательскими приложениями — создать арендатора и удалить его при каждом тесте. Как это:

    В вашем файле rails_helper.rb:

    ...
      config.before(:suite) do
        DatabaseCleaner.clean_with :truncation
        DatabaseCleaner.strategy = :truncation
      end
    
      config.before(:each) do
        Apartment::Tenant.drop('test') rescue nil
        Company.create! name: "LittleCompany", subdomain: "test"
        DatabaseCleaner.start
        Apartment::Tenant.switch! "test"
      end
    
      config.after(:each) do
        Apartment::Tenant.reset
        DatabaseCleaner.clean
        Apartment::Tenant.drop('test')
      end
    ...
    

    Конечно, это не очень быстро, но это единственный способ, который я нашел.

    25.01.2017
    Новые материалы

    Получение стоковых обновлений с помощью Python
    Для начинающего финансового аналитика Введение Описание: Этот проект Python создает скрипт для получения текущих обновлений акций с финансового веб-сайта Yahoo. Для этого проекта мы..

    Это все, что вам нужно знать о Kotlin в 2022 году
    Добро пожаловать! Kotlin — это язык программирования, популярность которого, кажется, растет, его действительно можно использовать для создания чего угодно, и если вы хотите узнать о Kotlin,..

    Текстовый графический интерфейс с Lanterna на Java
    Мой опыт работы с компьютерами (и текстовыми графическими пользовательскими интерфейсами) начался еще в восьмидесятых, когда я был ребенком, на дне рождения друга. Это был «новенький» Amstrad..

    Перезарядите свой мозг: умопомрачительный потенциал мозговых компьютерных интерфейсов
    Способность читать свои мысли и управлять объектами разумом долгое время были предметом человеческого любопытства, ограниченного областью научной фантастики… то есть до сих пор? С технологией,..

    Основы C# — Нулевой оператор объединения (??)
    Оператор ?? называется null-coalescing operator . Этот оператор используется для предоставления значения по умолчанию, если значение операнда в левой части оператора равно null ...

    Сравнение номеров версий в C++ с использованием синтаксического анализа строк
    Номера версий обычно используются для обозначения развития или обновлений программного обеспечения или любого другого продукта. При работе с номерами версий в C++ может быть полезно сравнить две..

    В мир искусственного интеллекта…
    ИИ — это новое топливо в современном мире. Куда бы вы ни обратились, с кем бы вы ни разговаривали — они, как правило, упоминают об ИИ хотя бы раз в ходе разговора. ИИ гудит повсюду. У каждого..