【问题标题】:Loading custom fixtures in Rails在 Rails 中加载自定义装置
【发布时间】:2014-03-29 13:07:32
【问题描述】:

我们正在尝试为使用与 ActiveRecord::Base 不同的数据库连接(在本例中继承自 Foo::Base)的一组模型加载固定装置。

我们创建了包含在 ActiveSupport::TestCase 中的这个模块,并指定了 .yml 文件的路径,例如foo_fitures :all。这对于运行的第一个测试非常有用。定义夹具访问器并在数据库中找到记录。但是对于后续的测试,数据库中没有记录。

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 的夹具系统有点复杂,我无法弄清楚我们缺少什么来确保加载额外的夹具。

【问题讨论】:

    标签: ruby-on-rails ruby fixtures


    【解决方案1】:

    好的。看起来可能是交易从数据库中删除了我们的固定装置。我的猜测是事务在我们的代码加载到夹具之前就已经开始了,所以这就是为什么它们在第一次测试时就在那里,但在第二次测试时就消失了。

    所以我们改变了策略,现在我们只钩入load_fixturesfixtures。这工作得很好。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 2014-05-10
      相关资源
      最近更新 更多