Rails 5.1 new framework defaults: what they do and how to safely uncomment them

Lily Reile
4 min readJun 24, 2021

When you run rails app:update on a Rails 5.0 app, it creates a file with 2 new default configuration settings. Here’s what they do and how to safely uncomment them.

This article assumes your application is on the 5.0 defaults. You can verify this by checking that load_defaults 5.0is present in your application.rb.

You’ll also want to make sure your app is stable on Rails 5.1 in production before getting started. Some flags are not backwards compatible with earlier Rails versions.

1. Rails.application.config.action_view.form_with_generates_remote_forms = false

What does this do?

You’ll notice that this flag isn’t commented-out in the new defaults file. Back in the 5.1 days, the Rails team was still figuring out the format of this file. Initially the flags were set to the old defaults—in this case, false—and you were meant to flip them—in this case, changing it to true.

Later on, the team standardized on having the flags be commented-out (with the value already flipped) and making you un-comment them in order to change the default.

With that piece of history out of the way, let’s take a look at what this flag actually does. The best way to understand it is to read about why this particular change was a mistake. Here’s my article on why Rails 6.1 reversed this setting.

To recap that article, setting this flag to true will start defaulting form_with to local: false, making them remote forms that submit via XHR.

How to safely flip?

Grep your codebase for form_with. This flag can be safely set to trueif there are no instances of it.

If there are instances of it, I recommend explicitly passing each of those instances the local: kwarg. This default (the implicit behavior when no local kwarg is passed) changes so much that it’s easier to not rely on it.

For each instance, if it does not have a local setting already, passing it local: true will continue the current (pre-flipping this flag) behavior.

Once all your form_with instances have a local setting, it’s safe to set this flag to true.

Gotcha!

Be careful when replacing this file with load_defaults 5.1. This particular flag is missing from the railties code. That means that when you delete this file like you’re supposed to, this flag will change back!

You could work around this by moving this flag to an initializer. However, I recommend just explicitly setting local everywhere so that you can not care about the default at all.

2. Rails.application.config.assets.unknown_asset_fallback = false

What does this do?

This flag is commented-out. It’s odd that the Rails team switched paradigms within the same file; but regardless, this one you are meant to un-comment like usual.

Okay, now what does it do?

Let’s consider this line of code in a Rails view:

<%= image_tag("icon.png") %>

This will output:

<img src="/assets/icon.png" />

Sprockets (the old-school version of the asset pipeline) found our image and resolved its full path relative to the root of our application.

Now, what happens when we reference an image that no longer exists (e.g., someone deleted it from the assets folder):

<%= image_tag("deleted_icon.png") %>

It still outputs:

<img src="/assets/deleted_icon.png" />

Sprockets knew the image was missing, but decided to ‘fall back’ on outputting the path where it ‘should be’ anyway. This is called ‘unknown asset fallback’.

That is surprising behavior that might only be noticed when a user sees a missing-image-box in production. That’s where this flag comes in.

Uncommenting this flag will make Sprockets throw an error instead of using unknown asset fallback. You’ll definitely notice that in development!

Keep in mind that this flag applies to all asset tag helpers, not just image_tag.

How to safely uncomment?

The risk with this flag is that, if you already have actively missing assets in production, those pages will now error instead of just being messed up.

As errors will only be thrown when those pages are requested, I recommend exercising all the pages in your application. Hopefully your test suite already does this, but you may want to click around to be sure.

Once you’re sure no assets are missing, it’s safe to uncomment this flag.

Edge case

Unknown asset fallback must have had a use-case for existing in the first place, right? Sometimes we know an image exists at a path despite it not being in our assets folder. Maybe that path is served by a CDN. Maybe we compile it outside of Rails and move it to that folder.

If you have this use-case, you can skip Sprockets altogether on an asset-by-asset basis like so:

<%= image_tag("icon_served_by_cdn.png", skip_pipeline: true) %>

This will emulate the old behavior of blindly returning the path, but now it’s explicit.

Now what?

Once these flags are flipped/uncommented, you don’t need config/initializers/new_framework_defaults_5_1.rb anymore. Delete that file and add load_defaults 5.1 to your config/application.rb.

Would you like to work with the latest Rails?

The Bridge Services team at Evidation Health is hiring! We always work with the latest tech — not to mention competitive pay and great WLB.

--

--