イニシャライザ内の値オブジェクトに対する「初期化により定数が自動ロードされる」ことを防止します
概要
Rails イニシャライザでは、次のように追加のアプリケーション構成を割り当てます。
module MyApp
class Application
config.x.email = {
default: '[email protected]',
invoice: '[email protected]'
}
end
end
しかし最近、これらの電子メール アドレスに値オブジェクト クラスを導入して、SPF/DKIM/DMARC と適切に調整するために必要なロジックをカプセル化する必要がありました。
module MyApp
class Application
config.x.email = {
default: EmailAddress.new('[email protected]'),
invoice: EmailAddress.new('[email protected]')
}
end
end
Rails 6.1 では、これにより警告がトリガーされます。
DEPRECATION WARNING: Initialization autoloaded the constant EmailAddress.
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 during
initialization does not run again. So, if you reload EmailAddress, for example,
the expected changes won’t be reflected in that stale Class object.
This autoloaded constant has been unloaded.
In order to autoload safely at boot time, please wrap your code in a reloader
callback this way:
Rails.application.reloader.to_prepare do
# Autoload classes and modules needed at boot time here.
end
That block runs when the application boots, and every time there is a reload.
For historical reasons, it may run twice, so it has to be idempotent.
Check the "Autoloading and Reloading Constants" guide to learn more about how
Rails autoloads and reloads.
この特定の場所でこのアドバイスにどのように従うべきかわかりません。
回避策として、require “email_address” をイニシャライザの先頭に追加すると警告が表示されなくなりますが、問題の根本的な解決にはなりません。
これに対処する方法はありますか?
ご協力いただきありがとうございます!
解決策
設定部分全体を to_prepare ブロックでラップする必要があります。
# config/initializers/email_config.rb
Rails.application.reloader.to_prepare do
Rails.application.config.x.email = {
default: EmailAddress.new("[email protected]"),
invoice: EmailAddress.new("[email protected]")
}
end
email_address.rb を lib ディレクトリに置いて、それを要求することもできます。EmailAddress の動作をすべて理解したら、再ロード可能にする必要はまったくありません。この場合、EmailAddress に変更を加えた場合は再起動が必要になります。
# config/initializers/email_config.rb
require "email_address" # => loads lib/email_address.rb
Rails.application.config.x.email = {
default: EmailAddress.new("[email protected]"),
invoice: EmailAddress.new("[email protected]")
}
もう 1 つのオプションは、autoload_once_paths に email_address.rb を含めることです。これは、これを要求することと同じですが、require を省略します。
# config/application.rb
config.autoload_once_paths << Rails.root.join("app/value_objects")
# config/initializers/email_config.rb
# EmailAddress will be loaded from app/value_objects/email_address.rb only once
Rails.application.config.x.email = {
default: EmailAddress.new("[email protected]"),
invoice: EmailAddress.new("[email protected]")
}
https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoloading-when-the-application-boots