NameError: неинициализированная константа и LoadError: Невозможно автоматически загрузить константу - PullRequest
2 голосов
/ 02 марта 2020

После обновления до Rails 5.0.1 я начал периодически получать NameError: uninitialized constant Payments::EventHandlers ошибки. Вот как определяется мой класс:

Код:

# app/managers/finance/payments/event_handlers/customer.rb
module Finance
  module Payments
    module EventHandlers
      class Customer < Finance::Payments::BaseStripeEventHandler
        # various methods
      end
    end
  end
end
# app/managers/finance/payments/base_stripe_event_handler.rb
module Finance
  module Payments
    class BaseStripeEventHandler < Finance::BaseStripeEventHandler
      # various methods
    end
  end
end
# app/managers/finance/base_stripe_event_handler.rb
module Finance
  class BaseStripeEventHandler
    # various methods
  end
end

Мне удалось воспроизвести эту ошибку на консоли Rails, как показано ниже:

Loading staging environment (Rails 5.0.1)
2.4.6 :001 > Finance::Payments::EventHandlers::Customer
 => Finance::Payments::EventHandlers::Customer
2.4.6 :002 > reload!
Reloading...
 => true
2.4.6 :003 > Finance::Payments::EventHandlers::Customer
NameError: uninitialized constant Finance

Итак, следуя https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#autoloading -изключен после загрузки в производственной среде , я изменил свой файл config/application.rb, как показано ниже:

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

После этих изменений я начал получать LoadError: Unable to autoload constant:

Loading staging environment (Rails 5.0.1)
2.4.6 :001 > Finance::Payments::EventHandlers::Customer
 => Finance::Payments::EventHandlers::Customer
2.4.6 :002 > reload!
Reloading...
 => true
2.4.6 :003 > Finance::Payments::EventHandlers::Customer
LoadError: Unable to autoload constant Finance::Payments::EventHandlers::Customer, expected .../app/managers/finance/payments/event_handlers/customer.rb to define it

Мне не ясно, является ли это структурой каталогов или как определяется класс customer. Может ли кто-нибудь дать совет, как это исправить?

Спасибо.

Изменения Я удалил config.autoload_paths += %W(#{config.root}/lib) из config/application.rb, и он все еще дает те же результаты. Спасибо за любую помощь в этом!

Правки 2 (реализовать предложение Романа Алексеева)

По предложению Романа Алексеева я добавил ниже:

# app/managers/finance.rb
module Finance; end
# app/managers/finance/payments.rb
module Finance
  module Payments
  end
end
# app/managers/finance/payments/event_handlers.rb
module Finance
  module Payments
    module EventHandlers
    end
  end
end

После этих изменений, я думаю, что я добился определенного прогресса, как указано выше. NameError больше не происходит в консоли после reload!.

Но когда мой работник запускает эту работу, это все еще возвращает это NameError: Worker выполняет следующий код:

scope = "Payments" # conditionally assigned
handler_class = "Invoice" # again, conditionally assigned
constant_name = "::Finance::#{scope}::EventHandlers::#{handler_class[:handler]}" # in this case ::Finance::Payments::EventHandlers::Invoice
Object.const_get(constant_name) 

Последнее приведенное выше утверждение возвращает NameError: uninitialized constant Payments::EventHandlers

# app/managers/finance/payments/event_handlers/invoice.rb
module Finance
  module Payments
    module EventHandlers
      class Invoice < Finance::Payments::BaseStripeEventHandler
        # various methods
      end
    end
  end
end

Ответы [ 2 ]

1 голос
/ 03 марта 2020

Я не уверен, но как предложение, что, если вы добавите этот файл и код в вашу структуру. В каталоге app/managers создайте файл finance.rb с кодом ниже

module Finance; end

В разделе app/managers/finance создайте файл payments.rb с кодом ниже

module Finance
  module Payments
  end
end

В разделе app/managers/finance/payments создайте файл ( если не существует) event_handlers.rb с кодом

module Finance
  module Payments
    module EventHandlers
    end
  end
end

У меня была похожая проблема, этот подход помог, надеюсь, он также поможет вам

0 голосов
/ 02 марта 2020

Это на самом деле зависит от вашей структуры папок. Не знаете, где вы хотите разместить файл base_event_handler.rb? Вы хотите сохранить его внутри папки event_handlers или внутри папки платежей ?

Это должна быть структура, если вы хотите, чтобы файл base_event_handler.rb находился внутри event_handlers папка:

module Finance
  module Payments
    module EventHandlers
      class Customer < Finance::Payments::EventHandlers::BaseEventHandler
        def method1
          puts "Hello there ---"
        end
      end
    end
  end
end

ПРИМЕЧАНИЕ. Определите Ваш файл base_event_handler.rb тоже, иначе вы получите NameError за отсутствие определения:

module Finance
  module Payments
    module EventHandlers
      class BaseEventHandler
        def methodE
          puts "This base event"
        end
      end
    end
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...