rails Initialization autoloaded the constant 問題
在採用 zeitwerk 進行 auto...
DEPRECATION WARNING: Initialization autoloaded the constant MyClass Being able to do this is deprecated. Autoloading during initialization is going to be an error condition in future versions of Rails. Reloading does not reboot the application, and therefore code executed duringinitialization does not run again. So, if you reload TyrSetting, for example,the expected changes won't be reflected in that stale Class object. This autoloaded constant has been unloaded.起因於如果我們在 config/initializers 下,呼叫了某個類別(class)例如 User,而 User 位於 app/models/user.rb 是沒有在 rails 啟動(initialize)之前先進行 require 的話,就會顯示這個棄用警告(deprecation warning)。
# config/initializers/foo.rb User.extend(FooModule)當修改過 FooModule 內容時,User 並不會因為 reload! 而跟著修改,只能 restart rails app。
# config/initializers/foo.rb ActiveSupport::Reloader#to_prepare do User.extend(FooModule) end如果是一些 Setting 之類需要在非常早期優先載入的 class
# config/application.rb module MyApp class Application < Rails::Application require 'setting
# config/initializers/foo.rb puts "1..." ActiveSupport::Reloader#to_prepare do puts "2..." end # config/initializers/bar.rb puts "3..." ActiveSupport::Reloader#to_prepare do puts "4..." end
1... 3... 2... 4...因此執行順序若會造成影響,則這裡需要特別注意。
# config/initializers/foo.rb require 'application_record' require 'user' require 'foo_module' User.extend(FooModule)這樣做在未來新版本時,仍會導致 reload! 無效或噴錯,因此不太建議用這種方式解,除非你也不打算升級更新了 😏。