0

I have a file in the lib directory of a rails 3 project called slot.rb. It creates a module called SojournerSupport, and contains a class called Slot. I have the following my config/application.rb file:

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

I then include the module in the model that I need it like so:

include SojournerSupport

This works fine locally on my machine, but when trying to run the app in heroku it says "uninitialized constant ShipRecord::SojournerSupport (NameError)" ShipRecord being the name of the model that I include the module in.

Any ideas or suggestions?

agmcleod
  • 13,321
  • 13
  • 57
  • 96

4 Answers4

3

I had a similar problem with getting my module to run on Heroku. In addition to the autoload naming convention, I found out that the module code must be required due to a threadsafe assumption made by the Rails' production environment on Heroku (even though it was commented out in my production.rb file.) As soon as I "required" the module file before for calling "include" on the module, everything started to work.

Please take a look at this excellent article on the subject of getting Modules to load correctly in Heroku:

http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/

Don Leatham
  • 2,694
  • 4
  • 29
  • 41
  • That's interesting. I've known it to be generally a bad idea to require your lib files, and to use the config as i said above. After skimming the article you linked, it sounds like the idea is to keep with the naming convention, or to manually require it as you did. – agmcleod Sep 06 '11 at 11:42
  • I tried it first, but unfortunately the naming convention would not work for me - as soon as I would push to Heroku things broke badly. Never really figured out why, but "require" saved the day. Can you enlighten me on why requiring lib files is a bad idea? Is there something lurking out there that I'll run into with this approach? – Don Leatham Sep 07 '11 at 05:41
  • Yes there is a reason: http://stackoverflow.com/questions/3356742/best-way-to-load-module-class-from-lib-folder-in-rails-3. If you read a comment below the answer that suggests using require, it says that requiring the files prevents ActiveSupport::Dependencies from unloading the code. – agmcleod Sep 07 '11 at 11:31
  • Thanks for the pointer. Makes sense. I'll query the Heroku guys to see what's up with threadsafe/require in their environment. – Don Leatham Sep 10 '11 at 19:21
0

If SojounerSupport is a top level class or module, then you might need to explicitly state it is so when including it.

include ::SojournerSupport
Douglas F Shearer
  • 25,952
  • 2
  • 48
  • 48
0

Not so much a solution as a way to get more information, but have you attempted to run rails with your production config from your local machine (using rails s production)?

If you run into the same problem there, I would investigate your production.rb file to see if it's doing anything strange with your autoload paths.

You could also load a console to your production environment (or a heroku console), and investigate your Application.config to ensure that the load paths are as you expect.

Finally, one of the first things I check when I'm seeing inconsistent Heroku / dev behavior is to ensure that I'm using a matching version of ruby. Heroku either still is or was recently using 1.8.7 as the default.

Ryan Brunner
  • 14,723
  • 1
  • 36
  • 52
0

Actually managed to figure out the solution. I'm not sure why heroku was crashing at the index page, but when i hit a controller that utilizes a model pulling in the library module, it would give me the error as well. It would seem that the config.autoload_paths expects the filename to be the same as the module name (as noted here: Rails 3 library not loading until require). I renamed the filename in the lib directory as such, and now it's working locally. I'll push to heroku when i get home, but I think this fixed the issue :).

Community
  • 1
  • 1
agmcleod
  • 13,321
  • 13
  • 57
  • 96