LoginSignup
29
16

More than 5 years have passed since last update.

Railsの config.eager_load はModelやControllerを読み込むタイミングを制御できる

Posted at

アプリケーション起動時にModelやControllerをごにょごにょするgemを開発していて気付いたことをメモ。
本記事は、ActiveRecordのeager_loadとはまた別の話なので注意。

eager load について

説明できる自信がないので、Railsの公式ドキュメントの説明に預けます。

config.eager_loadをtrueにすると、config.eager_load_namespacesに登録された事前一括読み込み(eager loading)用の名前空間をすべて読み込みます。ここにはアプリケーション、エンジン、Railsフレームワークを含むあらゆる登録済み名前空間が含まれます。

Railsのapp以下にあるクラス(ModelやController)をブート時に全て読み込む....といった感じでしょうか。

このconfig.eager_loadは通常、Railsの環境別にconfig/environments/xxxxxxxx.rbで設定されています。(rails newした時にそうなっているはず)

config/environments/development.rb
SampleApp::Application.configure do
#...(略)...
  # Do not eager load code on boot.
  config.eager_load = false
#...(略)...
end

eager load をしない場合の挙動

Railsアプリケーションで、config.eager_load = falseになっていると、そのクラスが存在するか?(定数が存在するか?)を確認しようとしても、クラスにアクセスする前ならばfalseが返ってきます。

コードを実行してみると、以下のような感じです。

irb
irb(main):001:0> Object.const_defined?('User')
=> false
irb(main):002:0> Object.const_defined?('UsersController')
=> false
irb(main):003:0> User
=> User(id: integer, name: string, email: string, created_at: datetime, updated_at: datetime, password_digest: string, remember_token: string, admin: boolean)
irb(main):004:0> Object.const_defined?('User')
=> true
irb(main):005:0> UsersController
=> UsersController
irb(main):006:0> Object.const_defined?('UsersController')
=> true

eager load をする場合の挙動

config.eager_load = trueにしている場合です。
以下の通り、クラスにアクセスする前から、クラスの存在確認(定数定義の確認)をできるようになっています。

irb
irb(main):001:0> Object.const_defined?('User')
=> true
irb(main):002:0> Object.const_defined?('UsersController')
=> true

eager_load! で強制的に読み込ませることもできる

ここまで述べてきた通り、config.eager_loadの値をtrueにすることで、Railsアプリケーション起動直後からクラスの存在確認をできるようになります。
が、どうしても、config.eager_loadの値によらず、クラスの存在確認をできるようにしたい場合、どうすればよいのでしょうか?

そこで登場するのが、Rails.application.eager_load!というメソッドです。
このメソッドは、config.eager_load = trueの時と同じロード処理をその場で実行してくれます。
(それなりの規模のアプリケーションだと実行に時間がかかるかと思います)

動かしてみると、こんな感じです。

irb
irb(main):001:0> Rails.application.eager_load!
=> ["/Users/ym/works/sample_app/app/assets", "/Users/ym/works/sample_app/app/controllers", "/Users/ym/works/sample_app/app/helpers", "/Users/ym/works/sample_app/app/mailers", "/Users/ym/works/sample_app/app/models", "/Users/ym/works/sample_app/app/controllers/concerns", "/Users/ym/works/sample_app/app/models/concerns"]
irb(main):002:0> Object.const_defined?('User')
=> true
irb(main):003:0> Object.const_defined?('UsersController')
=> true

通常は使わない方法かと思いますが、gem側で強制的にクラス存在確認を有効にしたい時など、どうしても必要になる時があるかもしれません。

29
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
16