Railsのアップデートの際に、新しいバージョンの config のデフォルト値を少しずつ反映させるときに new_framework_defaults_x_x
を使うと思います。
今回、config.load_defaults 6.1
へ上げる前に、Rails.application.config.active_record.has_many_inversing = true
の設定をしても反映されないことがありました。
たまたま今回は has_many_inversing でハマりましたが、他の設定でも同様ですし、new_framework_defaults 以外の config/initializers/*
での設定も同様にRails.application.config.xxx
の設定が反映されない可能性があるので記事にしてみました。
結論
初期化時の読み込み順によっては、config/initializers/*
のファイルの設定値が反映されないことがあるので、 その場合はconfig/application.rb
などのRails.application.initialize!
を実行する前に設定する必要があるようです。
RailsにもIssueとして上がっていました。
少し解説
今回、具体的な原因特定はできていないので、詳しくは上記のIssueを確認してください
Rails v6.1の実装の話をしますが、v7.0では少し変わっています
Rails.application.config.active_record.has_many_inversing
に値をセットすることで、ActiveRecord::Base.has_many_inversing
に値をセットすることができます。
ActiveRecord::Base.has_many_inversing
は内部でinvertible
かの判定に使われています1
今回、以下のように設定したのですが、
Rails.application.config.active_record.has_many_inversing = true
以下のように、ActiveRecord::Base.has_many_inversing
には値が反映されていませんでした。
[1] > Rails.application.config.active_record.has_many_inversing
=> true
[2] > ActiveRecord::Base.has_many_inversing
=> false
ちなみに、 config/application.rb に記述したところ、反映されていました。
Module Hoge
class Application < Rails::Application
# ...
config.active_record.has_many_inversing = true
# ...
end
end
調査をしたこと
ActiveRecord::Base.has_many_inversing
のgetterは以下で定義されています。
module ActiveRecord
module Core
extend ActiveSupport::Concern
included do
# ...
mattr_accessor :has_many_inversing, instance_accessor: false, default: false
値をセットしているところを確認すると、以下のようになっていました。
initializer "active_record.set_configs" do |app|
ActiveSupport.on_load(:active_record) do
configs = app.config.active_record
configs.each do |k, v|
send "#{k}=", v
end
end
end
ActiveSupport.on_load(:active_record)
のフックは、 ActiveRecord
がロードされると実行されるようです。
この処理が実行されるタイミングにログを仕込んでみたところ、初期化処理のload_config_initializers
のタイミングよりも早くに実行されていることがわかりました。
おそらく、どれかのgemなどで ActiveRecord
が読み込まれているのだと思われます。
今後
Rails側で、読み込みのタイミングにかかわらず、initializersで設定した内容が反映されるようになるといいですが、それまでは注意して確認する必要があります。
反映されない場合は config/application.rb
の初期化実行前にセットする必要があります。
config/initializers
でセットした内容が反映されないこともあるというのが盲点でもしかしたら他にもハマる人がいるかもしれないので、助けになると嬉しいです。
関連