tfantina
tfantina

Reputation: 815

Accessing modules in Rails lib folder

There are probably hundreds of these questions on here but I haven't been able to get one to work yet. I'm using Rails 6 and I always have trouble writing custom modules.

I have a file for creating email tokens: lib/account_management/email_token.rb

module AccountManagement
  module EmailToken
    def create_email_token(user)
       ....
    end
  end
end

Then in my controller I have tried all kinds of things: require 'account_management/email_token' include AccountManagement::EmailToken Calling it with: create_and_send_email_token(user)

At one point I added config.eager_load_paths << Rails.root.join('lib/account_management/') but I didn't think you still had to do that.

Whenever I try to call the controller action I get one of a few error messages:

*** NameError Exception: uninitialized constant Accounts::SessionsController::EmailToken
#this happens if I try to manually send through the rails console 
(although inside of a byebug I can call require 'account_management/email_token' and it returns
true.

Most commonly I get:

NoMethodError (undefined method `create_email_token' for #<Accounts::SessionsController:0x00007ffe8dea21d8>
Did you mean?  create_email):
# this is the name of the controller method and is unrleated.

Upvotes: 0

Views: 3951

Answers (1)

max
max

Reputation: 102423

The simplest way to solve this is by placing your files in app/lib/account_management/email_token.rb. Rails already autoloads any subdirectory of the app folder*.

/lib has not been on the autoload paths since Rails 3. If you want to add it to the autoload paths you need to add /lib not /lib/account_management to the autoload/eager loading paths. In Zeitwerk terms this adds a root where Zeitwerk will index and resolve constants from.

config.autoload_paths += config.root.join('lib')
config.eager_load_paths += config.root.join('lib')

Note that eager_load_paths is only used when eager loading is turned on. Its turned off by default in development to enable code reloading.

/lib is added to $LOAD_PATHso you can also manually require the file with:

require 'account_management/email_token'

See:

Upvotes: 4

Related Questions