Dependency loading confusion

Hey guys,

I have a module Foo::Bar, which extends ActiveRecord::Base with some custom functionality. This module is in lib/foo/bar.rb. Inside this file is also the code, that includes the module into ActiveRecord::Base:

    module Foo       module Bar         # stuff ...       end     end

    ActiveRecord::Base.send(:include, Foo::Bar)

Then, this file is required in config/initializers/foo.rb:

    require 'foo/bar'

The problem is, that sometimes i get this nasty error:

    A copy of Foo::Bar has been removed from the module tree but is still active!

and I really can't figure out what's the problem. The weird thing is that the error disappears when I restart the application, but sometimes appears again on a different page. It looks completely magical to me :slight_smile:

Everything works fine in test and production environments, so this has probably something to do with the Rails dependency loading/unloading magic.

So, I guess I can make it into a plugin, but it's really very simple and quite specific to my application, so it's not worth the effort. That's why I want to keep it only in lib.

Things I tried:

- Putting the lib/foo path into config.load_once_paths in config/ environment.rb - adding unloadable to the Foo::Base module - moving the include line (ActiveRecord::Base.send(:include, ...) into config/initializers/foo.rb

But nothing helps :frowning:

Any help will be appreciated. Thanks.

adam.

Hey guys,

I have a module Foo::Bar, which extends ActiveRecord::Base with some custom functionality. This module is in lib/foo/bar.rb. Inside this file is also the code, that includes the module into ActiveRecord::Base:

module Foo
  module Bar
    \# stuff \.\.\.
  end
end

ActiveRecord::Base\.send\(:include, Foo::Bar\)

Then, this file is required in config/initializers/foo.rb:

require 'foo/bar'

The problem is, that sometimes i get this nasty error:

A copy of Foo::Bar has been removed from the module tree but is

still active!

and I really can't figure out what's the problem. The weird thing is that the error disappears when I restart the application, but sometimes appears again on a different page. It looks completely magical to me :slight_smile:

What happens is that your app loads and serves the first request fine. Then rails unloads unloadable code. When the next request arrives, ActiveRecord::Base, which isn't reloadable now has the dead module included. Only development uses this way of loading classes

- Putting the lib/foo path into config.load_once_paths in config/ environment.rb

This should work. You do (if my memory is correct) need to use absolute paths though - check what's already in ActiveSupport::Dependencies.load_once_paths

Fred

Thanks for the reply Fred.

This should work. You do (if my memory is correct) need to use absolute paths though - check what's already in ActiveSupport::Dependencies.load_once_paths

It doesn't :frowning: I checked the content of ActiveSupport::Dependencies.load_once_paths and the lib/foo is there and it's an absolute path. It is first element of the list, all the others are plugins and gems paths. Not sure if I'm doing it correctly, but I put this into the Rails::Initializer.run { ... } block in the config/environment.rb:

    config.load_only_paths << "#{Rails.root}/lib/foo"

just after I define all gem dependencies.

Am I doing it right?

adam.

config\.load\_only\_paths &lt;&lt; &quot;\#\{Rails\.root\}/lib/foo&quot;

just after I define all gem dependencies.

Ah, don't forget to do require_dependency rather than require (or else you're half bypassing the rails dependency system and odd things can happen). Worth also sticking some breakpoints in AS::Dependencies to check that your file is being handled properly.

Fred

Ah, don't forget to do require_dependency rather than require (or else you're half bypassing the rails dependency system and odd things can happen). Worth also sticking some breakpoints in AS::Dependencies to check that your file is being handled properly.

Hey, that was it! Ok, now I understand the dependency loading voodoo little bit better :slight_smile: Thanks Fred.

adam.