简体   繁体   English

NameError:未初始化的常量和 LoadError:无法自动加载常量

[英]NameError: uninitialized constant and LoadError: Unable to autoload constant

After upgrade to Rails 5.0.1, I started getting intermittent NameError: uninitialized constant Payments::EventHandlers errors.升级到 Rails 5.0.1 后,我开始出现间歇性NameError: uninitialized constant Payments::EventHandlers错误。 Here is how my class is defined:这是我的类的定义方式:

Code:代码:

# 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

I was able to reproduce this error on Rails console as below:我能够在 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

So following https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#autoloading-is-disabled-after-booting-in-the-production-environment , I modified my config/application.rb file as below:所以按照https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#autoloading-is-disabled-after-booting-in-the-production-environment ,我修改了我的config/application.rb文件如下:

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

After these changes, I started getting LoadError: Unable to autoload constant :在这些更改之后,我开始收到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

I am not clear if it is a directory structure issue or the way customer class is defined.我不清楚这是目录结构问题还是customer类的定义方式。 Can someone provide guidance on how to fix it?有人可以提供有关如何修复它的指导吗?

Thanks.谢谢。

Edits I removed config.autoload_paths += %W(#{config.root}/lib) from config/application.rb and it is still giving same results.编辑我从config/application.rb删除了config.autoload_paths += %W(#{config.root}/lib)并且它仍然给出相同的结果。 Appreciate any help on this!感谢您对此的任何帮助!

Edits 2 (implement suggestion by Roman Alekseiev )编辑 2(执行 Roman Alekseiev 的建议)

As suggested by Roman Alekseiev, I added below:正如 Roman Alekseiev 所建议的,我在下面添加了:

# 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

After these changes, I think I have made some progress as above NameError is not occurring in the console anymore after reload!经过这些更改,我想我已经取得了一些进展,因为reload!后控制台中不再出现上述 NameError 了reload! . .

But when my worker runs this job, it is still returning this NameError: Worker is executing below code:但是当我的工人运行这个作业时,它仍然返回这个 NameError: Worker is execution 下面的代码:

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) 

Last statement above returns NameError: uninitialized constant Payments::EventHandlers上面的最后NameError: uninitialized constant Payments::EventHandlers语句返回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

I am not sure but as a suggestion what if you add this file and code to your structure.我不确定,但作为建议,如果您将此文件和代码添加到您的结构中会怎样。 Under app/managers directory create file finance.rb with code belowapp/managers目录下创建文件finance.rb ,代码如下

module Finance; end

Under app/managers/finance create file payments.rb with code belowapp/managers/finance创建文件payments.rb ,代码如下

module Finance
  module Payments
  end
end

Under app/managers/finance/payments create file (if not exist) event_handlers.rb with codeapp/managers/finance/payments event_handlers.rb用代码创建文件(如果不存在) event_handlers.rb

module Finance
  module Payments
    module EventHandlers
    end
  end
end

I had similar problem, this approach helped, hope it will help you also我有类似的问题,这种方法有帮助,希望它也能帮助你

This actually depends upon your folder structure.这实际上取决于您的文件夹结构。 Not sure where you want your base_event_handler.rb file to be ?不确定您希望 base_event_handler.rb 文件在哪里? Do you want to keep it inside event_handlers folder or inside payments folder ?你想把它放在event_handlers文件夹中还是在支付文件夹中?

This should be the structure if you want the base_event_handler.rb file to be inside event_handlers folder :如果您希望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

NOTE: Do define your base_event_handler.rb file too, else you will be getting NameError for not defining :注意:也要定义你的 base_event_handler.rb 文件,否则你会因为没有定义而得到 NameError :

module Finance
  module Payments
    module EventHandlers
      class BaseEventHandler
        def methodE
          puts "This base event"
        end
      end
    end
  end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM