Search code examples
ruby-on-railsruby-on-rails-6activesupportzeitwerk

Why Rails6+ started adding activesupport requires in config/environments/* by default?


I'm a bit late with Rails version upgrade. What surprised me was a bunch of active_support requires in config/environment/* files generated by Rails.

What are they for? Does it have something to do with Zeitwerk that was introduced in Rails6? I don't remember them being present in older versions of Rails.

ag ^require config/environments
config/environments/development.rb
1:require "active_support/core_ext/integer/time"

config/environments/test.rb
1:require "active_support/core_ext/integer/time"

config/environments/production.rb
1:require "active_support/core_ext/integer/time"

Steps to reproduce:

rails new myapp

cat Gemfile  | grep "^gem 'rails'"
gem 'rails', '~> 6.1.3', '>= 6.1.3.2'

I tried to find this update in rails/rails CHANGELOG and some git blaiming but that didn't help.


Solution

  • A little bit further down each environment file, the code that the require statement loads is used (or is referenced in comments, in the case of the production file). From the default development.rb:

    # Enable/disable caching. By default caching is disabled.
    # Run rails dev:cache to toggle caching.
    if Rails.root.join('tmp/caching-dev.txt').exist?
      config.cache_store = :memory_store
      config.public_file_server.headers = {
        'Cache-Control' => "public, max-age=#{2.days.to_i}" # <- NOTE THIS LINE
      }
    else
      config.action_controller.perform_caching = false
    
      config.cache_store = :null_store
    end
    

    That require statement adds support for expressions like 2.days.to_i - core_ext/integer/time loads some functions, but also requires core_ext/numeric/time.

    So the require statement is being a good Ruby citizen, and making sure that the particular part of Rails that its code relies upon is guaranteed to be loaded in order to be able to parse that line correctly.

    I don't know why it wasn't needed before (it could be a Zeitwerk-related issue, as you suggest, that's a part of Rails 6+ I'm not too familiar with yet).

    But at the end of the day, if the whole Rails stack is loaded before this file is evaluated, the require won't have any additional effect – and if it's not, this file will load what it needs and then the rest of Rails will load as needed.