What Does load_defaults Do?

What Does load_defaults Do?

Let’s begin with a simple question:

Have you seen config.load_defaults 6 in any application?

6 is an argument and could vary, I’m just giving an example.

While upgrading a Rails application from 5.1 to 6.0 we had an “easy” question.

Should We Run the rails app:update Command?

The quick answer is: yes, we should, why not?!

After running the rails app:update command, there are many file changes that the command did for us.

It was time to run the test suite, and guess what? Everything failed. The next step forward was to undo all the changes and start with a single configuration change we thought would be easy and safe. Then we added the config.load_defaults 6.0 line and ran the test suite again. It was still failing.

Just to double-check, we commented that line back and ran the test suite. Everything was passing, so that little line was ruining everything.

We decided to focus on config.load_defaults 6.0.

We searched for def load_defaults in rails core to see what load_defaults does. Take your time to understand it.

Tip: You can easily navigate the rails repository using https://github.dev/rails/rails More about GitHub editor

If you are not able to navigate to the rails core code, I added the load_defaults method below.

  # rails/railties/lib/rails/application/configuration.rb

  def load_defaults(target_version)
    case target_version.to_s
    when "5.0"
      # rails 5.0 default configuration
    when "5.1"
      load_defaults "5.0"
      # rails 5.1 default configuration
    when "5.2"
      load_defaults "5.1"
      # rails 5.2 default configuration
    when "6.0"
      load_defaults "5.2"
      # rails 6 default configuration
    when "6.1"
      load_defaults "6.0"
      # rails 6.1 default configuration
    when "7.0"
      load_defaults "6.1"
      # rails 7 default configuration
    when "7.1"
      load_defaults "7.0"
      # rails 7.1 default configuration
    else
      raise "Unknown version #{target_version.to_s.inspect}"
    end

    @loaded_config_version = target_version
  end

The first thing that caught my attention was the fact that it calls the same load_defaults method recursively with the previous rails version as an argument.

def load_defaults(target_version)
  case target_version.to_s
  when "5.1"
    load_defaults "5.0" # here
  when "5.2"
    load_defaults "5.1" # here
  when "6.0"
    load_defaults "5.2" # here
  else
  end
end

That means it will load the default configuration for the version you indicated and also all the previous versions as a fallback.

Example: If you use config.load_defaults("6.1") in your Rails application, it will implement load_defaults for version 6.0, 5.2, 5.1 and 5.0 as a fallback.

Which is good, because you won’t need to add all those configuration lines in your own project.

What Does load_defaults Do?

In simple words, the load_defaults method is loading default rails configurations starting from Rails 5 up to Rails 7.1 (since it’s currently the latest version). You can inspect each configuration and what they do over here.

So, Why Does My Application Fail?

After reviewing the application, we noticed config.load_defaults had been removed in a previous update, when we added it back, it threw an error because the load_defaults method for the current version of Rails enabled config.belongs_to_required_by_default = true

Changing config.belongs_to_required_by_default to false did the trick to solve the issue.

Should We Use It?

This is such a great question, the quick answer is maybe! LOL.

The longer answer is: How have you used the rails configurations before? If you have always been using the load_defaults config, it seems to be safe to use in your next update.

If you haven’t used it, first make sure to read every single rule in the default values section and double-check your application is compatible with all of them.

I hope this can help you at some point, until next time.

You only fail when you stop trying - Unknown

Get the book