rails: Rails console reload! does not eager load when told to

Steps to reproduce

Using the following STI class structure, with eager loading on.

# config/development.rb
config.eager_load = true

# app/models/class_a.rb
class ClassA < ActiveRecord::Base
  def self.types
    descendants.map(&:name)
  end
end

# app/models/class_b.rb
class ClassB < ClassA
end
rails c
Loading development environment (Rails 4.2.6)
irb(main):001:0> ClassA.types
=> ["ClassB"]
irb(main):002:0> reload!
Reloading...
=> true
irb(main):004:0> ClassA.types
=> []

Expected behavior

The reload! command should of reloaded all of the eager loaded content.

Actual behavior

The reload! command does not seem to reload all the eager loaded content.

System configuration

Rails version: Rails 4.2.6 Ruby version: ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 2
  • Comments: 16 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Digging through ActiveSupport::Reloader docs and Autoloading and Reloading Constants guide, I’ve ended up with the following:

# config/initializers/eager_reloading.rb
Rails.application.reloader.after_class_unload do  
    Rails.application.eager_load! if Rails.application.config.eager_load
end

Seems to work like a charm for me - both for console reload! and development code reloading. Rails 5.2.1 / Ruby 2.5.1-p57

As long as cache_classes is false, it should work… but it does sound plausible that it’ll ignore eager_load, and just unload things, leaving them to autoload when mentioned.

If that’s the case, it should be fairly straight-forward to plug the desired behaviour into the Reloader. PRs welcome. 😄

I’m able to reproduce this issue on a new Rails 4.2.6 project following the steps above. (Although I’m not sure how to write an isolated test for it since it seems to rely on having loading a whole Rails app).