2014-02-26 5 views
1

Мы пытаемся загрузить светильники для группы моделей, использующих другое соединение с базой данных, чем ActiveRecord :: Base (наследующее от Foo :: Base в этом примере).Загрузка пользовательских светильников в Rails

Мы создали этот модуль, который мы включили в ActiveSupport :: TestCase, и укажите путь к файлам .yml и, например, foo_fitures :all. Это отлично работает для первого теста. Адаптеры Fixture определены и записи находятся в базе данных. Но для последующих тестов в базе данных нет записей. арматуре система

module Foo::Fixtures 
    extend ActiveSupport::Concern 

    included do 
    setup :setup_foo_fixtures 
    teardown :teardown_foo_fixtures 

    class_attribute :foo_fixture_path 
    class_attribute :foo_fixture_table_names 

    self.foo_fixture_table_names = [] 
    end 

    module ClassMethods 
    def foo_fixtures(*fixture_names) 
     if fixture_names.first == :all 
     fixture_names = Dir[foo_fixture_path.join("**/*.yml")].map { |f| File.basename(f, ".yml") } 
     else 
     fixture_names = fixture_names.flatten.map { |n| n.to_s } 
     end 

     self.foo_fixture_table_names |= fixture_names 
     require_fixture_classes(fixture_names) 
     setup_fixture_accessors(fixture_names) 
    end 
    end 

    def setup_foo_fixtures 
    @loaded_fixtures.merge!(load_foo_fixtures) 
    end 

    def teardown_foo_fixtures 
    Foo::Base.clear_active_connections! 
    end 

    private 

    def load_foo_fixtures 
    foo_classes = Foo::Base.subclasses.flat_map { |klass| klass.abstract_class ? klass.subclasses : klass } 
    class_names = foo_classes.each_with_object({}) do |klass, memo| 
     memo[klass.table_name.to_sym] = klass if klass.table_name.present? && foo_fixture_table_names.include?(klass.table_name) 
    end 
    foo_fixtures = ActiveRecord::Fixtures.create_fixtures(foo_fixture_path, foo_fixture_table_names, class_names) do 
     Foo::Base.connection 
    end 
    Hash[foo_fixtures.map { |f| [f.name, f] }] 
    end 
end 

Rails' немного запутанным, и я не в состоянии понять, что нам не хватает, чтобы убедиться, что загружены наши дополнительные светильники.

ответ

0

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

Итак, мы изменили стратегию, и теперь мы просто подключаемся к load_fixtures и fixtures. Это прекрасно работает.

module FooFixtures 
    module ClassMethods 
    def foo_fixture_classes 
     collect_subclasses = ->(k) { k.abstract_class ? k.subclasses.flat_map(&collect_subclasses) : k } 
     Foo::Base.subclasses.flat_map(&collect_subclasses) 
    end 

    def foo_fixture_path 
     Rails.root.join("test/foo_fixtures") 
    end 

    def foo_fixture_table_names 
     Dir[foo_fixture_path.join("**/*.yml")].map { |f| File.basename(f, ".yml") } 
    end 

    def fixtures(*fixture_names) 
     super 
     if fixture_names.first == :all 
     require_fixture_classes(foo_fixture_table_names) 
     setup_fixture_accessors(foo_fixture_table_names) 
     end 
    end 
    end 

    private 

    def load_fixtures 
    foo_fixture_path = self.class.foo_fixture_path 
    foo_fixture_table_names = self.class.foo_fixture_table_names 
    class_names = self.class.foo_fixture_classes.each_with_object({}) do |klass, memo| 
     memo[klass.table_name.to_sym] = klass if klass.table_name.present? && foo_fixture_table_names.include?(klass.table_name) 
    end 
    foo_fixtures = ActiveRecord::Fixtures.create_fixtures(foo_fixture_path, foo_fixture_table_names, class_names) do 
     Foo::Base.connection 
    end 

    super.merge(Hash[foo_fixtures.map { |f| [f.name, f] }]) 
    end 
end 

class ActiveSupport::TestCase 
    extend FooFixtures::ClassMethods 
    prepend FooFixtures 

    self.foo_fixture_classes.each do |fixture_class| 
    set_fixture_class fixture_class.table_name.to_sym => fixture_class 
    end 

    ... 
end 
Смежные вопросы