Search code examples
ruby-on-railsrubyruby-on-rails-5

Rails: Loading custom class from lib folder in controller


I've created a file as lib/services/my_service.rb.

# /lib/services/my_service.rb
class MyService
...
end

I want to use it in app/controllers/my_controller

class MyController < ApplicationController
     def method
          service = MyService.new()
     end

I'm getting an error that MyService is an uninitialized constant. I've tried to import it with

require '/lib/services/my_service.rb'

But I'm getting

cannot load such file -- /lib/services/my_service.rb

Edit: I have tried autoloading from application.rb using

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

But no dice. Still getting uninitialized constant MyController::MyService


Solution

  • Ruby on Rails requires following certain naming conventions to support autoloading.

    Rails can autoload a file located at lib/services/my_service.rb if the model/class structure was Services::MyService.

    Change your lib/services/my_service.rb to:

    module Services
      class MyService
        # ...
      end
    end
    

    And use that class like this in your controller:

    service = Services::MyService.new
    

    Please note that depending on your Ruby on Rails version, you might need to add the lib folder to the list of folders which are queried when looking for a file to autoload:

    # add this line to your config/application.rb:
    config.autoload_paths << "#{Rails.root}/lib"
    

    Read more about autoloading in the Rails Guides.