Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NameError: uninitialized constant on Heroku

I have a Rails 5 application with some modules/classes located under /lib. In development I can access those through the rails console like so:

irb(main):001:0> MyClass.do_something

In Production on Heroku I get this:

irb(main):001:0> MyClass.do_something
NameError: uninitialized constant MyClass

As you might have guessed I autoload the /lib directory in my application.rb:

config.autoload_paths << Rails.root.join('lib')

However, the most curious thing about this is, that I can access this class from rake tasks. So something like this works fine:

task do_something: :environment do
  MyClass.do_something
end

Which tells me that the class is present on Heroku.

Any ideas?

like image 610
Severin Avatar asked Aug 11 '17 12:08

Severin


1 Answers

Rails doesn't autoload in production for thread safety, instead eager loading application constants. You can fix your issue by using the eager_load_paths method instead.

config.eager_load_paths << Rails.root.join('lib')

If you still want to autoload in development you can make it conditional

load_path_strategy = Rails.env.production? ? :eager_load_paths : :autoload_paths
config.public_send(load_path_strategy) << Rails.root.join('lib')

If you really need autoloading of this directory in production you can set enable_dependency_loading to true.

config.enable_dependency_loading = true
config.autoload_paths << Rails.root.join('lib')

See this blog post for more explanation.

like image 112
m. simon borg Avatar answered Sep 17 '22 20:09

m. simon borg