Petros Kalafatidis
Petros Kalafatidis

Reputation: 765

rails uninitialized constant Module Name

I have an integrations folder under app directory. I can see that this path is loaded

 ActiveSupport::Dependencies.autoload_paths
 "/appname/app/integrations"

then inside this path I have another folder with a nested module

"/appname/app/integrations/moduleA/base_service.rb"
# frozen_string_literal: true

module Integrations
  module ModuleA
    class BaseService

But when I am trying to use the class

Integrations::moduleA::BaseService
::Integrations::moduleA::BaseService

both of them giving me

NameError: uninitialized constant Integrations

Upvotes: 1

Views: 2737

Answers (1)

max
max

Reputation: 102368

The way the rails autoloader works (both the classical and Zeitwerk) is that the immediate subdirectories of the /app folder are "root" directories. That means that the autoloader will look for root level constants in all of these directories.

Thus if you want to define Foos::Bar you would need to place the file in app/foos/foos/bar.rb.

If you want to avoid that and place the constant in app/integrations/module_a/base_service.rb you would need to push the directory with a custom namespace to Zeitwerk:

loader.push_dir(Rails.root.join('app', 'integrations'), namespace: Integrations)

With the classic autoloader the solution was to add the /app folder to the autoloading/eager_loading paths as a root as well.

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

So that the autoloader will look for Integrations::ModuleA in app/integrations/module_a.rb.

See:

Upvotes: 4

Related Questions