Zeitwerk overwriting values set in initializers in Rails 6


Ran into something interesting while trying to use ActiveSupport::Configurable in Rails 6. It appears the OrderedHash created by ActiveSupport::Configurable is being overwritten in my development environment only.

I have a module Foo with a class Bar as follows:

module Foo
  class Bar
    include ActiveSupport::Configurable

    def self.request_body
        'client_id' => my_client_id,
        'client_secret' => my_client_secret

and its corresponding initializer

Foo::Bar.configure do |c|
  if Rails.env.production? || Rails.env.staging?
    %i[my_client_id my_client_secret].each do |key|
      # set for prod and staging using Rails credentials
  elsif Rails.env.test?
    %i[my_client_id my_client_secret].each do |key|
      # set for test
    %i[my_client_id my_client_secret].each do |key|
      c[key] = '1234'

If I insert byebug at the end of my initializer, start the rails console and call

Foo::Bar.config #=> {:my_client_id=>"1234", :my_client_secret=>"1234"}

But when I exit byebug and reach the console prompt and run the above I get an empty hash.

I have found two “workaround” solutions. In development.rb, setting config.cache_classes to true allows the OrderedHash to be set as expected. Likewise, reverting to the classic autoloader in application.rb with config.autoloader = :classic produces the expected outcome.

I have read the docs at Autoloading and Reloading Constants (Zeitwerk Mode) — Ruby on Rails Guides but can’t quite figure out what is happening here.

Any insight would be appreciated.

Thank you

Hi! Do you see a warning in the logs when the application boots?