Railsでconfig配下に置く各種初期化ファイルについて、それぞれのユースケースや実行の順番について整理しておきます。
今回はRailsガイドでも挙げられている、代表的な初期化コードの配置および定義場所を扱います。
- config/application.rb
- config/environments 配下
- config/initializers 配下
- initialization events
config/application.rb
Railsアプリケーションの起動時にgemなどに依存しない、1番はじめに実行させたい共通の初期化コードを書きます。
Rails::ApplicationはRails::Railtieを間接的に継承しているため、config/application.rbでinitializerメソッドを使用して、アプリケーションの初期化処理を定義することができます。
config/environments 配下
環境毎の初期化コードが書かれた設定ファイルを置きます。
例えば、config/environments/production.rbなどが該当します。
config.active_storage.service
を、環境毎に:local
や:amazon
などに変更するような使い方をイメージするとよいです。
config/initializers 配下
環境にかかわらず共通で行う初期化コードが書かれた設定ファイルを置きます。
gemやRailsのフレームワークで使用する初期化コードが置かれることが多いです。
initialization events
Rails::Application, Rails::Railtie, Rails::Engineのサブクラスで使用可能な初期化時のイベントフックが5つ存在します。
- before_configuration
- before_initialize
- to_prepare
- before_eager_load
- after_initialize
after_initialize
使用されることが多いイベントフックで
- Railsアプリケーション(フレームワーク)の初期化が完了した後の初期化コード
- gemに依存する初期化コード
などを書きます。
実行の順番
実行の順番についてまとめておくとそれぞれ、以下となります。
初期化の順番
- config/application.rb
- config/environments 配下
- config/initializers 配下
また、config/initializers配下のファイルの読み込みの順番はアルファベットや数字の並び順にファイルが読み込まれるため、01,02のようなプレフィックスをファイル名につけることで、実行の順番を保証することができます。
初期化イベントの呼び出される順番
- initialization events
- config/application.rbに定義
- config/environments 配下に定義
- config/initializers 配下に定義
実際に動かしてみる
実際に各初期化ファイルやコードがどの順番で実行されているかも確認しておきます。
開発者モード(RAILS_ENV=development)で検証しています。
config/application.rb
class Application < Rails::Application
...
puts "config/application.rb"
...
end
config/environments/development.rb
Rails.application.configure do
...
puts "config/environments/development.rb"
...
end
config/initializers/application_controller_renderer.rb
...
puts "config/initializers/application_controller_renderer.rb"
...
config/initializers/mime_types.rb
...
puts "config/initializers/mime_types.rb"
...
結果
config/application.rb
config/environments/development.rb
config/initializers/application_controller_renderer.rb
config/initializers/mime_types.rb
上記に加えて、各ファイルでafter_initializeを定義してみます。
config/application.rb
class Application < Rails::Application
...
puts "config/application.rb"
Rails.application.config.after_initialize do
puts "config/application.rb | after_initialize"
end
...
end
config/environments/development.rb
Rails.application.configure do
...
puts "config/environments/development.rb"
Rails.application.config.after_initialize do
puts "config/environments/development.rb | after_initialize"
end
...
end
config/initializers/application_controller_renderer.rb
...
puts "config/initializers/application_controller_renderer.rb"
Rails.application.config.after_initialize do
puts 'config/initializers/application_controller_renderer.rb | after_initialize'
end
...
結果
config/application.rb
config/environments/development.rb
config/initializers/application_controller_renderer.rb
config/initializers/mime_types.rb
↓after_initialize↓
config/application.rb | after_initialize
config/environments/development.rb | after_initialize
config/initializers/cors.rb | after_initialize
Config gemを使う場合の注意
ここからは番外編です。
定数値を管理するためにConfig gemがよく使用されるかと思いますが、gem側で初期化のタイミングを必ず一番はじめに強制する挙動があるため注意が必要です。
特に、Config gemの初期化の前に、Rails.applicationの初期化に依存する事前処理を行いたい場合に考慮が必要となります。
initialization eventsのbefore_configuration
を使用したとしても、対象の処理をConfig gemの初期化処理よりも前に持ってくることができません。
これは、Config gemがRails::Railtie
を継承したクラス内で、before_configuration
を定義することで初期化のタイミングをトップレベルに持ってきていることによる挙動となります。
そのため、config/initializers/config.rb
の初期化ブロックの一番最初の処理として、Rails.applicationの初期化に依存する処理を書くことになります。
Config.setup do |config|
Rails.application...
...
end
参考
https://guides.rubyonrails.org/initialization.html
https://guides.rubyonrails.org/configuring.html
https://github.com/rubyconfig/config/blob/master/lib/config/integrations/rails/railtie.rb