0

In Rails, there is a lib directory. It is not autoloaded by default. So when you load the Rails environment, all the modules and classes in this folder will not be known at runtime. I tried to autoload lib in the application.rb:

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

But it does not work. It does not load the modules and classes in lib I want loaded.

File structure is as so:

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

I have this in factory.rb:

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

And in pa_factory.rb:

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

When I load rails console, and I get empty array when I run:

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

The reason why array is empty is because the PaFactory is not loaded in memory. This is despite the fact that I included lib to autoload path! So why is not not autoloaded #1?

Also, I added the following to factory.rb:

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

And it gives me error:

RuntimeError: Circular dependency detected while autoloading constant Docket::PracticeFactory::Factory

Interesting error, I am loading files with *_factory.rb and factory.rb does not have an underscore, but those other files do inherit from Factory. How can this error be avoided?

Daniel Viglione
  • 8,014
  • 9
  • 67
  • 101
  • Note that I deleted my other post about Docket::PracticeFactory.constants(true) not returning any of the classes defined in this Module. That is related to this issue - the fact that autoload_paths does not work and does not load the files in lib directory and therefore Docket::PracticeFactory.constants(true) does not see the constants because they are not loaded in memory. – Daniel Viglione Mar 28 '18 at 19:16

1 Answers1

1

I have nothing to say about autoloading, the magic never worked for me and I try to avoid it wherever possible.

For the latter, the error cause is clear: you try to load PbFactory that requires Factory class to be defined (since it derives from it,) and it is not yet defined. To resolve an issue just put your

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

after the Factory class declaration.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160