7

I have a custom class stored in /lib (/lib/buffer_app.rb):

require 'HTTParty'

class BufferApp
  include HTTParty
  base_uri 'https://api.bufferapp.com/1'

  def initialize(token, id)
    @token = token
    @id = id
  end

  def create(text)
    message_hash = {"text" => text, "profile_ids[]" => @id, "access_token" => @token}

    response = BufferApp.post('/updates/create.json', :body => {"text" => text, "profile_ids[]" => @id, "access_token" => @token})
  end
end

I'm attempting to use this this class in an Active Admin resource and get the following error when in production (Heroku):

NameError (uninitialized constant Admin::EventsController::BufferApp):

It's worth noting I have this line in my application.rb and that this functionality works locally in development:

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

If I try include BufferApp or require 'BufferApp' that line itself causes an error. Am I having a namespace issue? Does this need to be a module? Or is it a simple configuration oversight?

jokklan
  • 3,520
  • 17
  • 37
Jayson Lane
  • 2,828
  • 1
  • 24
  • 39

3 Answers3

8

I had exactly the same problem with Rails 5 alpha. To solve it, I had to manually require the file:

require 'buffer_app'

and not: (require 'BufferApp')

Even if Michal Szyndel's answer makes great sense to me, after manually requiring the file, prefixing :: to the constant was non influential in my case.

Anyway I am not satisfied with the manual requiring solution because I need to add code which is environment specific. Why don't I need to require the files manually in development?

masciugo
  • 1,113
  • 11
  • 19
6

Change this

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

to this

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

eager_load_paths will get eagerly loaded in production and on-demand in development. Doing it this way, you don't need to require every file explicitly.

See more info on this answer.

Jonathan Tran
  • 15,214
  • 9
  • 60
  • 67
  • 2018-Nov-2, Thank you! This work perfectly, I put my class in /lib/ folder, it work in development mode, but not production mode. so I add new `config.eager_load_paths` into `config/application.rb` then it work! – NamNamNam Nov 02 '18 at 09:25
3

Error line says it all, you should reference class as ::BufferApp

Mike Szyndel
  • 10,461
  • 10
  • 47
  • 63
  • 1
    To elaborate: you will need `::` in front to specify that the `BufferApp` is defined in the root namespace (without namespace). Otherwise will it try to find `BufferApp` in your current namespace (`Admin::EventsController`). – jokklan Jun 20 '13 at 13:57
  • This makes total sense... thank you guys! However, I still get the following: NameError (uninitialized constant BufferApp), is this likely the result of the lib dir not being properly loaded? – Jayson Lane Jun 20 '13 at 14:12
  • I included the path in require and was able to get it working: require "#{Rails.root}/lib" + '/buffer_app.rb' although I don't believe this is ideal – Jayson Lane Jun 20 '13 at 14:38