【问题标题】:Circular dependency detected while autoloading constant in lib directory在 lib 目录中自动加载常量时检测到循环依赖
【发布时间】:2018-09-07 14:05:23
【问题描述】:

在 Rails 中,有一个 lib 目录。默认情况下不会自动加载。所以当你加载 Rails 环境时,这个文件夹中的所有模块和类在运行时都不会被知道。我试图在application.rb 中自动加载lib:

config.autoload_paths += %W(#{config.root}/app/models/ckeditor #{config.root}/lib)

但它不起作用。它不会加载我想要加载的 lib 中的模块和类。

文件结构如下:

\lib
  \docket
    \practice_factory
      factory.rb
      pa_factory.rb

我在 factory.rb 中有这个:

module Docket
  module PracticeFactory
    class Factory
      def self.practice_methods
        descendants.collect {|descendant| descendant.practice_methods }
      end
    end
  end
end

在 pa_factory.rb 中:

module Docket
  module PracticeFactory
    class PaFactory < Factory
      def self.practice_methods
        {
            some: 'data',
            more: 'stuff'
        }
      end
    end
  end
end

当我加载 rails 控制台时,我在运行时得到空数组:

Docket::PracticeFactory::Factory.practice_methods
 => [] 

array 为空的原因是 PaFactory 没有加载到内存中。尽管我将 lib 包含到了自动加载路径中!那么为什么不自动加载 #1 呢?

另外,我在 factory.rb 中添加了以下内容:

Dir["#{Rails.root}/lib/docket/practice_factory/*_factory.rb"].each {|file| require file }

它给了我错误:

RuntimeError:自动加载常量时检测到循环依赖 Docket::PracticeFactory::Factory

有趣的错误,我正在加载带有 *_factory.rb 的文件,而 factory.rb 没有下划线,但那些其他文件确实继承自 Factory。如何避免这个错误?

【问题讨论】:

  • 请注意,我删除了关于 Docket::PracticeFactory.constants(true) 不返回此模块中定义的任何类的其他帖子。这与这个问题有关 - autoload_paths 不起作用并且不会加载 lib 目录中的文件,因此 Docket::PracticeFactory.constants(true) 看不到常量,因为它们没有加载到内存中。

标签: ruby-on-rails ruby


【解决方案1】:

我对自动加载没什么好说的,魔法对我从来没有用过,我尽量避免它。

对于后者,错误原因很明确:您尝试加载需要定义Factory 类的PbFactory(因为它派生自它),但尚未定义。要解决问题,只需将您的

Dir["*_factory.rb"].each {|file| require_relative file }

Factory 类声明之后。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多