Rails Framework Defaults: Defusing the Time Bomb in Your Upgraded App


Summarized using AI

Rails Framework Defaults: Defusing the Time Bomb in Your Upgraded App

Josh Puetz • July 10, 2025 • Philadelphia, PA • Talk

Overview

In the talk "Rails Framework Defaults: Defusing the Time Bomb in Your Upgraded App" from RailsConf 2025, Josh Puetz explains a crucial but often overlooked step in the Rails upgrade process: handling and upgrading Rails framework defaults. While most tutorials focus on getting a new version running, Puetz advocates completing the process by addressing framework defaults to prevent future issues.

Main Topic

The core theme is that upgrading your Rails version is not truly finished until you've updated your app's framework defaults, which helps avoid potential breakages and keeps the app aligned with best practices and security standards.

Key Points

  • What Are Rails Framework Defaults?

    • Defaults are suggested configuration settings provided by the Rails team.
    • They control Rails’ behavior across various components like ActiveRecord and ActionView.
    • Unlike custom config values, defaults regularly change between Rails versions to encourage best practices, reduce boilerplate, and prepare for deprecations.
  • Examples of Defaults Changing:

    • config.active_record.belongs_to_required_by_default switched from false (pre-Rails 5) to true (Rails 5+), enforcing presence on associations.
    • action_dispatch.cookies_same_site_protection became lax by default in Rails 6.1, improving cookie security.
    • action_view.button_to_generates_button_tag in Rails 7 now yields a proper <button>, instead of an <input>.
  • The Role of Defaults Files:

    • Two main files manage defaults:
    • application.rb with config.load_defaults, locking in a version’s default settings.
    • config/initializers/new_framework_defaults_X.rb files, where each new default is listed (commented-out) for incremental opt-in by developers after upgrades.
    • The upgrade process does not automatically change these values, preventing sudden breakage but leaving apps on outdated settings if unaddressed.
  • Risks of Ignoring Defaults:

    • Keeping old defaults is likened to a “time bomb,” creating technical debt.
    • Security, performance, and compatibility improvements in newer Rails versions can be missed.
    • Third-party gems and tutorials often assume current defaults, and mismatches can cause issues.
  • Best Practices for Upgrading Defaults:

    • Preparation:
    • Audit current test coverage and pass all tests before changing defaults.
    • Research:
    • Review all relevant new_framework_defaults files and related Rails guides/documentation.
    • Investigate each default—its purpose, impact, and any migration work needed (e.g., cookie rotation for security changes).
    • Upgrade Approaches:
    • Fast method: Change everything at once (discouraged unless necessary).
    • Slow, incremental method: Uncomment each default one by one, test, deploy, and monitor stability before proceeding to the next. Consider using feature flags for safer rollouts.
    • Finalize:
    • Once all new defaults are adopted and stable, update config.load_defaults to the latest version and remove override files.
  • Suggestions for Rails Team:

    • Improve documentation in upgrade guides and new_framework_defaults files, ideally linking to the relevant pull requests or issues for context.

Conclusion and Takeaways

  • A Rails upgrade is incomplete without updating framework defaults: failing to do so can lead to technical debt and future emergencies.
  • Developers are encouraged to review and update defaults methodically and collaboratively, preparing the codebase for continued health and maintainability.
  • Proactive management of framework defaults is a "future kindness" to the app and the team, preventing last-minute crises and ensuring ongoing Rails compatibility.

Rails Framework Defaults: Defusing the Time Bomb in Your Upgraded App
Josh Puetz • Philadelphia, PA • Talk

Date: July 10, 2025
Published: July 23, 2025
Announced: unknown

Yay, you did it: you upgraded Rails and it's live in production! All done, right? Not so fast: most upgrade talks and tutorials skip over the important step of upgrading Rails framework defaults. Your Rails upgrade isn't really done until you've disarmed the time bomb of outdated defaults. It can be tricky and isn't well documented, but you can do it with these steps.

RailsConf 2025

00:00:16.960 Hi everybody. Thanks for coming to my
00:00:18.960 talk. Um, you could go to a different
00:00:21.520 one. I really wouldn't mind. It's fine.
00:00:24.720 Um, this talk is entitled Rails Default:
00:00:27.199 Diffusing the Time Bomb in Your Upgraded
00:00:28.880 App. and apologies for the absolute uh
00:00:31.439 buzzfeedworthy clickbait title.
00:00:34.399 Um, but this talk is mostly a talk about
00:00:36.880 the Rails upgrade that comes after your
00:00:39.440 Rails upgrade. So to start, I want you
00:00:42.719 to envision your next Rails upgrade. So
00:00:45.840 maybe think about your Rails upgrade
00:00:48.239 vision board. You guys like make vision
00:00:50.879 boards for your upgrades, right? Is that
00:00:52.559 just Okay. Well, digital anesthetic.
00:00:55.120 Perfect. Um, so when you think about
00:00:58.640 your beautiful Pinterest board that
00:01:00.480 envisions your Rails upgrade, what are
00:01:02.960 you done? What what is the point at
00:01:05.199 which you're like, "Yes, we have done
00:01:06.720 it. You can unfurl the banner." Well, I
00:01:09.760 bet when I think you're done is
00:01:11.680 different than when you think you're
00:01:12.799 done. There's one last step that a lot
00:01:15.840 of the upgrade guides don't mention, and
00:01:18.080 that's what this talk is going to cover.
00:01:20.479 So, hi, I'm Josh. Um, I'm a senior Rails
00:01:24.320 developer with years of experience. Uh
00:01:27.280 I'm currently a program currently
00:01:29.119 developer at Donut. We're an employee
00:01:31.200 experience platform that integrates into
00:01:32.880 Slack and we handle everything from
00:01:34.320 onboarding to employee rewards to
00:01:37.920 employee satis satisfaction, all sorts
00:01:40.000 of stuff like that. So check us out.
00:01:43.600 So I have a confession.
00:01:46.399 I really like Rails upgrades. Like I
00:01:49.520 know I'm the only one. Um I'm the only
00:01:52.000 one in fact that that at Donut I am the
00:01:54.479 Rails upgrade guy because nobody else
00:01:57.119 likes to do them. So I get them all. Um
00:01:59.920 I really like that there's like a plan.
00:02:01.439 There's a defined start. There's a
00:02:03.360 defined end. There's a recipe along the
00:02:06.079 way. It reminds me a lot about baking. I
00:02:07.680 love baking too. You start out, you
00:02:10.000 follow the instructions. You measure
00:02:11.840 everything. You're careful. And you end
00:02:13.520 up with a beautiful cake or a beautiful
00:02:16.480 Rails deployment at the end.
00:02:19.520 So recently at Donut, we went through a
00:02:22.000 series of Rails upgrades from version
00:02:24.239 five to version 7. And we did this in
00:02:26.879 the kind of recommended way. We went
00:02:28.480 really slow, really careful. We didn't
00:02:31.200 go from 50 to 70. We went one uh
00:02:34.560 incremental version at a time. And near
00:02:37.840 the end of that process, I noticed a new
00:02:41.040 file uh in config initializers. We had
00:02:44.800 new framework defaults_7
00:02:47.599 RB and I did not make this file. Um, and
00:02:51.120 in fact, since the 70 is on there, I
00:02:53.840 figured this must be some sort of a new
00:02:55.760 file. And actually, it was worse than
00:02:58.560 that. There were a lot of these files.
00:03:03.360 Now, this is kind of a weird naming um
00:03:06.319 um uh scheme, but I'm no stranger to it.
00:03:10.480 In fact, I might have used a similar
00:03:13.040 naming scheme for this keynote,
00:03:17.440 but it got me wondering
00:03:19.680 what the are new framework
00:03:21.440 defaults. Sorry. Sorry confir.
00:03:25.599 I hadn't seen this covered in many
00:03:27.200 guides. And that's what I want to talk
00:03:29.120 to you about today because I've heard
00:03:30.560 from a lot of people that they also did
00:03:32.239 not know what this is. So, here's what
00:03:34.480 we're going to cover again. What the
00:03:36.959 heck are they?
00:03:39.280 How do they get loaded? How do they
00:03:41.200 work?
00:03:43.040 Why should you even care about them? If
00:03:45.120 you haven't worried about them up until
00:03:46.560 now, why is now the time you should
00:03:48.080 start caring? And finally, after I
00:03:50.720 expertly convince you that you should
00:03:52.319 care about them, because you know, I'm
00:03:53.840 speaking and that's kind of like key to
00:03:55.280 this talk. Um, we're going to form a
00:03:57.040 plan to upgrade the defaults in your
00:03:58.640 application.
00:04:00.480 Okay, so first off, what are they? What
00:04:03.680 is even a default? Well, default values
00:04:06.720 are configuration settings that
00:04:08.319 influence Rails behavior. They're just
00:04:10.879 like any other configuration setting
00:04:12.560 that you've probably seen in application
00:04:14.080 RB files like that, but they're a little
00:04:17.600 different. They're configuration
00:04:18.799 settings with an opinion. With most
00:04:21.040 configuration settings, it's totally up
00:04:22.320 to you. Set whatever you want. Defaults
00:04:24.479 are different. Defaults have a suggested
00:04:27.199 value from the Rails team.
00:04:30.560 They're usually configured in
00:04:31.840 application RB, but they can be
00:04:33.360 configured in initializers or really
00:04:35.520 anywhere else that the Rails boot
00:04:37.280 process touches.
00:04:42.160 So, uh, also should, uh, note that they
00:04:45.759 impact all sorts of parts of Rails.
00:04:47.759 They're not lo uh they're not limited to
00:04:50.000 just the startup procedure. They can
00:04:51.759 touch the entire stack. So, let's do an
00:04:55.120 example. Do you remember social media?
00:04:58.160 Um, so many of the Rails conicle example
00:05:02.479 classes are related to social media. So
00:05:04.400 let's go old school and consider a post
00:05:06.880 and a post has many comments and thus a
00:05:09.919 comment belongs to a post. Okay, great.
00:05:13.360 Well, there is a configuration setting
00:05:16.800 config.activerecord.bongs
00:05:19.520 to required by default and you'll see
00:05:21.759 this with a lot of configuration
00:05:23.120 settings and defaults. config dot and
00:05:25.759 then the portion of rails the library
00:05:27.280 that it's in active record action helper
00:05:29.600 stuff like that and then the name of the
00:05:31.680 default so config.active active record
00:05:34.800 that belongs to required by default.
00:05:38.000 The default setting is true. Okay, so if
00:05:41.680 I don't ever specify this configuration
00:05:43.759 in application RB, Rails is going to
00:05:46.320 assume the value is true. And what does
00:05:48.560 it do? Well, it requires that a belongs
00:05:50.800 to association be populated when saving
00:05:52.960 a child record. So if I construct a
00:05:56.240 blistering internet comment but do not
00:05:58.720 put a post in it, I will get an error
00:06:01.520 thrown by active record when I try to
00:06:03.039 save it. That makes sense, right? That's
00:06:05.360 like pretty basic.
00:06:07.600 But what if I told you it wasn't always
00:06:09.440 like this? Before Rails 5, the default
00:06:12.560 value was actually false. You wouldn't
00:06:14.720 get an error at all from active record.
00:06:16.800 You hopefully would get an error from
00:06:18.400 your database, but no promises.
00:06:21.600 So, if the default before Rails 5 was
00:06:24.880 false and the default now is true, why
00:06:28.080 did the defaults change? Well, there's a
00:06:31.199 couple of reasons and I will say this is
00:06:33.120 all conjecture. I'm not on the Rails
00:06:35.039 core team. I have never successfully
00:06:38.080 contributed a PR to Rails. So, I'm
00:06:40.880 guessing what some of the intentions are
00:06:42.639 based on Rails documentation and things
00:06:45.199 I've read in the issues.
00:06:47.360 So the first thing that a lot of the PRs
00:06:49.759 and issues that change defaults mention
00:06:52.800 are embracing better practices. So
00:06:55.360 defaults are a way we can move
00:06:56.880 developers from one way of doing things
00:06:59.120 to another and we do it in a slow
00:07:01.199 matter. We might think hey we like
00:07:04.639 database constraints now. We like it
00:07:06.880 when active record warns us and not the
00:07:08.720 database throws an error. Can move
00:07:10.800 developers in that direction by setting
00:07:12.400 a different default.
00:07:14.400 we can reduce boilerplate code. A lot of
00:07:16.960 the Rails default uh the conversation
00:07:19.039 around Rails defaults deal with noticing
00:07:21.440 that developers are constantly having to
00:07:23.360 set a particular um option in their code
00:07:26.240 or they're having to set a particular
00:07:27.680 option in config and setting the default
00:07:30.720 helps reduce that boilerplate.
00:07:34.160 This one's a little trickier. Preparing
00:07:35.919 for future dep uh deprecations.
00:07:38.400 Sometimes the Rails team knows a feature
00:07:41.360 isn't so hot or is going to be moved
00:07:43.360 away for something. So they'll set a
00:07:45.440 default opposite of that to slowly move
00:07:48.000 developers away from it. And this is
00:07:49.599 like again a very slow process. We're
00:07:51.520 not talking like one revision of Rails.
00:07:53.759 We're talking over many.
00:07:59.120 So here's an example belongs to required
00:08:01.840 by default. Our um example from post and
00:08:04.720 comment. So all the way back in 2014,
00:08:08.479 this new developer noted that almost
00:08:11.120 every belongs to declaration seems to be
00:08:13.919 a required association. And it's rare
00:08:15.759 that you would allow a foreign key to be
00:08:17.440 nil, which is probably what you were all
00:08:19.280 thinking when you heard that the default
00:08:20.639 was false. So let's turn it on to true
00:08:23.680 and have false be something that you
00:08:25.280 have to opt into. Great.
00:08:29.120 Um here are some more examples of
00:08:31.120 changes just for flavor over the years.
00:08:33.599 Um in rail 6 action dispatch return only
00:08:37.680 media type on content type. You'll also
00:08:40.479 notice these have wonderfully succinct
00:08:42.399 names. Um the previously the default was
00:08:46.560 false and what that meant was when you
00:08:48.399 got an HTTP response from controllers
00:08:50.720 they would only include the media type
00:08:52.480 that's something like text/html.
00:08:55.120 Well, in Rails 6, the default changed to
00:08:57.120 true. That said that you would also
00:08:59.360 receive a character um set like usually
00:09:01.760 UTF8.
00:09:04.320 Um in Rails 6.1, the action
00:09:07.600 dispatch.cookies
00:09:09.120 same site protection was the default was
00:09:11.839 changed to lax. Before this, the default
00:09:14.880 was null. So what cookie same site
00:09:17.360 production protection does is set a
00:09:22.160 security option on the HTTP set cookie
00:09:25.120 header. There's a couple of different
00:09:26.640 options you can set all the way from
00:09:28.720 pretty loose to strict and lax is middle
00:09:31.279 of the road, but it's wild to me that
00:09:33.120 before 6.1 there was no default
00:09:35.600 specified. So you wouldn't get the set
00:09:38.399 cookie header.
00:09:41.279 And in Rail 7, action view.button Button
00:09:44.160 two generates button tag. This is like a
00:09:46.720 personal favorite of mine. Um the
00:09:48.880 default was changed to true and it
00:09:50.880 previous was previously was false.
00:09:52.800 Before Rail 7, if you use the button to
00:09:56.080 form helper, you would get an input tag
00:09:59.120 of type button. It's a little weird.
00:10:02.080 With the default um set to true after
00:10:04.240 Rails 7, you would get a proper HTML
00:10:06.640 button tag.
00:10:09.279 Okay, so this is all great. Wonderful.
00:10:11.440 Thank you, Rails. But wait, what if your
00:10:13.920 app wanted the old default? What if you
00:10:16.240 needed an input tag of type button or
00:10:19.519 you needed the set cookie header to be
00:10:23.120 false? I don't know why that would be,
00:10:24.160 but maybe you didn't need it. Well, what
00:10:25.839 if your app needed those old defaults?
00:10:28.000 Well, congratulations. Your app is now
00:10:30.880 broken.
00:10:32.560 Is it any wonder why Rails upgrades get
00:10:34.959 such a bad rap?
00:10:37.680 So the Rails team saw this, realized
00:10:40.079 this is not a great situation, and
00:10:42.240 that's where Rails framework defaults
00:10:44.480 come into play. They're there to help
00:10:47.760 get around this potential problem of
00:10:49.200 apps breaking.
00:10:51.279 So there's two files that work together.
00:10:55.040 The first is config/lication
00:10:57.680 rb, and that's where we've talked about
00:10:59.279 a lot of configuration settings get
00:11:01.040 made. The second file we're going to
00:11:03.600 talk about is an app initializers new
00:11:06.160 framework defaults
00:11:08.240 51 52 etc etc etc.
00:11:12.959 So let's talk about application RB
00:11:14.800 config uh let's talk about application
00:11:16.480 RB first. There is a configuration
00:11:19.120 setting that was added in Rails 5.1
00:11:21.839 which we'll get to called uh config.load
00:11:24.720 defaults. And what this tells Rails is
00:11:28.000 what version of defaults you want to
00:11:30.160 take. It locks in the behavior and it
00:11:32.560 also does that up to your specified
00:11:34.240 version. So for example, if you are
00:11:37.360 running rails 6 and it's a brand new
00:11:40.000 application and you want to take all of
00:11:42.320 the defaults that were changed all the
00:11:44.079 way up to Rails 6, great. You're going
00:11:46.399 to go ahead and set config.load defaults
00:11:48.320 to 6.0.
00:11:51.200 Now, if you have an application that you
00:11:52.880 are upgrading, the Rails upgrade process
00:11:55.279 will not touch this number. This number
00:11:57.360 is set in stone. So you don't have to
00:11:59.360 worry about this changing underneath
00:12:00.480 you. And that way your application is
00:12:02.800 not not going to just spontaneously
00:12:04.079 break because there are new Rails
00:12:05.440 defaults.
00:12:07.360 And like I mentioned, this number is
00:12:09.360 kind of cool because you get everything
00:12:10.959 before it for free.
00:12:15.040 Okay, the second file we have to talk
00:12:17.279 about are new framework defaults, star
00:12:20.399 and friends. Um, you could have one or
00:12:23.200 you could be like my application have a
00:12:24.959 lot of them.
00:12:26.639 And what this file does, it lets you
00:12:28.560 incrementally opt into all of the new
00:12:31.600 defaults.
00:12:33.600 So, I'll show you an example in a
00:12:35.040 second, but this file is created by the
00:12:37.200 Rails upgrade process because it's
00:12:38.560 specific to the version of Rails that
00:12:40.079 you're upgrading to. And it lists out
00:12:42.800 all of the brand new defaults that are
00:12:45.600 created or being changed with this
00:12:47.279 version of Rails. And they're all
00:12:48.800 commented out. And the idea is you as a
00:12:51.680 developer can uncomment them one by one
00:12:54.320 and opt in as you go along.
00:12:57.360 Now the idea also is that at some point
00:12:59.440 in the future you will hopefully
00:13:01.839 uncomment all of the defaults in the
00:13:03.920 file and then you can get rid of this
00:13:06.959 file and increment config.load defaults
00:13:10.160 version in application.rb.
00:13:12.880 So, let's take a look at an example. And
00:13:14.959 this is a little imprecise because I've
00:13:16.639 got two examples. And just like we
00:13:19.920 preach, Rails is living it in um in
00:13:22.800 transparency for everyone to see. So, in
00:13:25.120 Rails 5, the first version of this file,
00:13:27.760 this is new framework defaults.rb. This
00:13:30.399 is the one without a number and the
00:13:32.240 you'll first see it starting with Rails
00:13:33.760 5. And what's interesting about this is
00:13:36.720 the defaults are uncommented and the
00:13:39.920 defaults all have their old value. So
00:13:42.959 take a look at that first line.
00:13:43.920 Rails.lication.config.actioncontroller.perform
00:13:48.560 CSFR tokens equals false. And the
00:13:50.959 comment above it says that the previous
00:13:52.399 version is false. So this is kind of
00:13:54.240 weird. If you want to take the new
00:13:55.839 version, you need to manually flip it.
00:13:58.720 Well, you can see how that might have
00:14:00.880 gone. Developers got a little confused.
00:14:03.279 it was really hard to tell without the
00:14:05.279 comments what the previous value was.
00:14:08.079 When was the last time someone added
00:14:09.440 this file on your team etc. So starting
00:14:11.600 with Rails 5.1 and then continuing to
00:14:13.519 today the format of new framework uh the
00:14:16.639 framework excuse me the format has
00:14:20.399 changed now this file comes with
00:14:23.760 everything commented out and it also
00:14:26.240 comes with the brand new default coded
00:14:29.519 into. So here was our friend
00:14:31.760 rails.lication application.config.action
00:14:35.040 view dotbutton 2 generates button tag
00:14:38.320 all the way at the bottom. And you can
00:14:39.600 see it's commented out and the value is
00:14:41.760 set to the new framework default value
00:14:43.920 which is true. So when I'm ready to take
00:14:45.760 this value, I can just uncomment that
00:14:48.160 line and I'm good to go.
00:14:50.720 Okay, so some of you might be wondering
00:14:53.680 that's great nice talk. But if
00:14:57.600 config.load load defaults never changes.
00:15:00.880 Can I just leave it where it's at? Can I
00:15:03.360 just set it and forget it? We never have
00:15:05.360 to touch this, right? Well, not quite
00:15:08.720 for a couple of reasons. My talk depends
00:15:11.360 on it. And number two, there are other
00:15:13.279 reasons why you're want going to want to
00:15:14.800 upgrade this file.
00:15:17.040 So, yeah, older apps don't automatically
00:15:20.079 get the new defaults, so they're not
00:15:21.680 going to break underneath you. That's
00:15:24.079 like a pro, but it's also a con. your
00:15:27.760 apps defaults are B your app's
00:15:29.519 configuration are partially frozen in
00:15:32.079 time you're not going to get any of the
00:15:35.120 newer features you're not going to get
00:15:38.240 some of the benefits we talked about
00:15:40.079 warning about deprecations new security
00:15:42.720 information etc
00:15:46.639 is going to remove these old defaults
00:15:48.959 and you're going to have to go back to
00:15:51.440 manually specifying what you want your
00:15:53.759 option to be
00:15:55.839 like we talked about with same site,
00:15:57.360 same site lacks. A lot of these defaults
00:15:59.120 are perform uh sorry, excuse me. Um, a
00:16:01.199 lot of these defaults are performance
00:16:02.720 and security related.
00:16:05.839 This is one that has bit us a lot. Gems
00:16:08.800 and tutorials generally expect Rails to
00:16:11.759 be running on the latest version of the
00:16:13.839 defaults. So, you might take a gem and
00:16:16.639 it might assume that you have your set
00:16:19.199 cookie header set or that you're going
00:16:21.120 to get a warning or an error if you
00:16:23.519 don't populate a belongs to association.
00:16:26.399 And if your application isn't doing
00:16:28.000 that, you can run into problems.
00:16:32.000 And given that you're going to run into
00:16:33.920 a variety of these issues, I guarantee
00:16:36.160 you there is some point in the future
00:16:37.839 that you are going to have to make this
00:16:39.680 upgrade. Just like you could never
00:16:42.480 upgrade your Rails application, but
00:16:44.560 you're probably going to have to at some
00:16:46.160 point in the future. And when that time
00:16:48.079 comes, you're in for a world of hurt if
00:16:50.320 you're going to be slogging through four
00:16:52.079 or five upgrade versions. you're going
00:16:54.000 to be in for a world of hurt if you're
00:16:55.839 slogging through four or five default
00:16:57.920 upgrades as well.
00:17:00.800 And that's why I assert that leaving
00:17:04.000 your app on old default is a time bomb
00:17:06.400 waiting to go off. Okay, so what can we
00:17:09.760 do about it? Well, let's make a game
00:17:12.559 plan.
00:17:14.240 First of all, you need to do a little
00:17:15.760 bit of prep work. Just like with a Rails
00:17:17.280 upgrade, you need to make sure that you
00:17:19.839 are taking a look at your test suite
00:17:21.919 coverage level.
00:17:23.679 Um, take a look at where where the what
00:17:26.400 parts of your codebase that your tests
00:17:28.160 cover. Are you a little light on the
00:17:29.760 back end? Are you maybe a a little light
00:17:32.480 or not at all on the front end? Where
00:17:35.520 are the holes in your test coverage?
00:17:37.919 Make a note of that and keep that in
00:17:39.679 mind for later on when we take a look at
00:17:41.360 what different defaults touch. And then
00:17:44.160 also, it goes without saying, you got to
00:17:45.840 make sure your tests pass. Like if your
00:17:48.080 tests are failing in Maine, number one,
00:17:51.280 let's have a talk after this. But
00:17:54.400 but number two, you're not going to know
00:17:57.200 if one of your default changes has
00:17:58.880 broken your code or not.
00:18:01.919 Okay, so this is the part that I spent
00:18:04.000 the most time on, and this is research.
00:18:06.960 You need to review the upgrades guides.
00:18:10.480 So, if I had done my due diligence and
00:18:12.880 carefully read the Rails upgrade guides,
00:18:14.960 which I thought I did, I would have seen
00:18:17.440 that yes, default files are mentioned in
00:18:20.880 the Rails upgrade. I would argue they're
00:18:22.480 near the bottom and not as prominent,
00:18:24.320 but they are mentioned. There is some
00:18:27.200 information in the upgrade guide about
00:18:28.799 what some of the defaults do. Um, also
00:18:32.320 importantly, some of these defaults
00:18:34.400 require you to do a little bit of
00:18:35.840 pre-work on the current version of Rails
00:18:38.160 that you're on. Specifically, stuff
00:18:39.679 that's related to caching and um um
00:18:42.799 cryptographic signing. You might have to
00:18:44.880 write something like a cookie rotator to
00:18:47.200 prepare for changing the default in the
00:18:49.120 future.
00:18:51.440 You should read through all those new
00:18:53.120 framework default files. There's a
00:18:54.880 little bit of documentation in there
00:18:56.080 about what they do. You can also kind of
00:18:57.760 guess from the name of the default what
00:19:00.240 part of Rails it's touching and you can
00:19:02.320 map that on to where your application is
00:19:05.200 strong or light in test coverage.
00:19:08.640 It's the part I spent a lot of time on.
00:19:11.520 Research the changes in Rails source
00:19:13.600 code and the pull requests. It's a
00:19:15.919 little bit of documentation in new
00:19:17.440 framework defaults file but not enough
00:19:19.360 to my liking and there's a lot of
00:19:21.919 context that's missing. So, for example,
00:19:24.799 why is the same site default now lax?
00:19:28.080 What are the other options?
00:19:31.039 Good luck. Um, so you're probably going
00:19:33.200 to have to look around for blog posts or
00:19:35.360 worst case look into the um Rails um
00:19:38.000 repo on GitHub and try to find the
00:19:40.400 originating issue and the originating
00:19:42.320 pull request to get some of that
00:19:43.520 context.
00:19:45.760 And once you have that, you can research
00:19:47.840 in your app what kind of effect it's
00:19:49.840 going to have.
00:19:52.559 For example, um, one of the Rails
00:19:55.200 upgrades changed a bunch of defaults
00:19:56.960 related to active storage. Well, our
00:19:59.360 application at Donut doesn't use active
00:20:01.200 storage. So when I don't have to worry
00:20:03.440 so much about those defaults.
00:20:07.039 Now that we've done all of that, we get
00:20:09.039 to pick our path. And we've got two
00:20:10.880 options. We can go fast and we can go
00:20:13.120 slow. And I bet you can guess which one
00:20:15.600 I'm going to suggest. And it's not this
00:20:18.240 one. But maybe you're feeling lucky. So
00:20:21.600 great, let's go fast and furious. If you
00:20:24.240 want to just go for broke and maybe, you
00:20:26.640 know, it's a brand new version of Rails
00:20:28.320 that you didn't do anything to and
00:20:30.799 you're upgrading. I don't know. I can't
00:20:32.159 really come up with a reason why you'd
00:20:33.200 want to do this fast, but maybe you have
00:20:34.559 to. You're going to set config.load
00:20:37.280 defaults to the current version of Rails
00:20:39.120 that you're on that you've just upgraded
00:20:40.799 to.
00:20:42.559 Then you're going to delete the new
00:20:44.960 framework defaults override file.
00:20:47.679 Then you will consult whatever deity you
00:20:50.159 pray to
00:20:52.080 deploy and fix those breakages quickly
00:20:55.039 because stuff is probably going to
00:20:57.039 break.
00:20:59.039 All right, you can probably guess which
00:21:00.720 option I would recommend you do and that
00:21:02.799 is slow and steady.
00:21:05.840 So in slow and steady, we're going to
00:21:07.360 enable the settings one by one. We're
00:21:09.440 not going to look at config um uh
00:21:11.440 application.rbconfig.load
00:21:13.120 defaults yet. We're going to our new
00:21:14.559 framework defaults file. going to pick
00:21:16.559 one like the button or same site uh HTTP
00:21:19.520 cookies or what an interesting config.
00:21:22.000 We're going to uncomment it.
00:21:24.960 We might consider using feature flags.
00:21:27.200 This is something that I've had to do
00:21:28.720 occasionally where even though I'm
00:21:31.360 taking a default and I've done my
00:21:33.039 research, I'm not 100% sure how it's
00:21:36.320 going to go and I'd like a quick way to
00:21:39.039 turn it off. So I might surround like
00:21:41.919 say if I've got a belongs to I might
00:21:43.679 surround it with a feature flag
00:21:45.200 something like flipper that I can turn
00:21:46.640 off easily in production. One thing
00:21:49.360 about config.rb and the new framework
00:21:51.440 defaults files they get loaded at
00:21:53.440 initialization time. So if I want to
00:21:55.360 change it I need to restart my
00:21:56.880 application with a feature flag. I can
00:21:58.559 just turn it on and off.
00:22:01.760 Consider setting a default value. You
00:22:04.480 know the defaults are just suggestions
00:22:06.559 and they're great suggestions but they
00:22:08.400 don't work for everyone. And so they
00:22:10.080 really are configurable. There might be
00:22:12.080 config uh there might be defaults that I
00:22:14.080 decide are not right for my application.
00:22:16.320 Maybe I'm not ready. Maybe my
00:22:18.240 application specifically depends on the
00:22:19.919 old one and I don't want to make the
00:22:21.360 code change. But for whatever whatever
00:22:23.520 reason, if there is a configuration um
00:22:25.520 option that I want to keep, I'm going to
00:22:27.919 move it over into another initializer
00:22:30.320 file or into config.rb.
00:22:34.240 And then you're going to test, you're
00:22:36.000 going to deploy, and you're going to
00:22:37.360 monitor. You're going to look for
00:22:38.480 breakages, but you're also going to look
00:22:39.760 for performance problems, weird log
00:22:42.159 spam, anything that looks strange. And
00:22:45.120 then you're going to repeat this process
00:22:46.880 until some glorious day you get through
00:22:50.880 all of the default the new framework
00:22:53.520 defaults and they're all uncommented.
00:22:55.440 And at that point, you can delete the
00:22:57.679 file and rev config.load defaults
00:23:00.240 version. And then you can celebrate
00:23:03.039 because you're done. and you've achieved
00:23:05.039 the vision on your Pinterest vision
00:23:06.960 board
00:23:09.600 until next time when we're going to do
00:23:11.760 it all over again.
00:23:15.120 So, that leads me to um a little sidebar
00:23:19.120 if you guys want to just join me over
00:23:20.400 here. Um I don't know if anyone from
00:23:21.760 Railscore is here. I kind of I hope
00:23:24.240 they're not because this part gets a
00:23:25.679 little spicy. Um,
00:23:28.240 so if you've contributed to Rails, if
00:23:30.480 you are on Rails Core, if you're making
00:23:32.080 any change, I have like just a request.
00:23:36.080 Could you possibly just a little improve
00:23:39.360 the explanations of the changes in the
00:23:41.120 upgrade guide? A lot of this stuff is
00:23:43.440 really, really in the weeds. So, better
00:23:46.320 information in the upgrades guide would
00:23:48.000 go a long way. Similarly, the inline
00:23:51.679 documentation and new framework
00:23:53.200 defaults, that would be an excellent
00:23:54.799 place to do things like link to the PR
00:23:58.240 or link to the issue that created this
00:24:02.320 change. Um, new framework defaults is
00:24:05.200 the first time a lot of developers are
00:24:06.559 going to bump into this and if there's
00:24:08.080 not a good link to where they should go,
00:24:10.400 they're kind of flying blind. And I
00:24:11.760 think that's why a lot of people just
00:24:13.039 see this commented out file and they
00:24:14.960 think, well, it's commented out. I don't
00:24:16.320 have to do anything with this.
00:24:18.960 My argument is that you shouldn't make
00:24:20.320 developers delve into the source code to
00:24:22.559 understand these changes. You know,
00:24:24.240 imagine a new version of Rails came out
00:24:25.919 and they're like, "Hey, there's a new
00:24:27.279 feature action cable. Go research it."
00:24:31.440 We would never stand for that. No, we
00:24:33.440 provide great documentation. And so I
00:24:35.600 think we should do the same thing with
00:24:37.200 defaults.
00:24:39.200 Okay. So, every time I go to RailsCom, I
00:24:41.840 come back with my team with a billion
00:24:44.159 things I want to do, and I drive them
00:24:45.679 absolutely nuts with too many of them.
00:24:47.679 So, I want to leave you with just a few
00:24:49.840 things you should do next Monday or
00:24:52.720 maybe Tuesday when you get back into the
00:24:54.400 office.
00:24:56.320 So, first, review application.rb and
00:24:59.520 figure out what your current default
00:25:01.279 version is. Remember that's in
00:25:03.200 config.load defaults.
00:25:06.320 audit all those beautiful new framework
00:25:08.320 default files in your app. Do you have
00:25:10.799 any? Has someone uncommented them? Well,
00:25:13.600 that's a great place for a get blame.
00:25:15.600 Um,
00:25:17.919 but see which ones you have.
00:25:21.840 Talk with your team about the upgrade
00:25:23.679 plan. This is not something to do on
00:25:26.799 like a summer Friday or a bug fix
00:25:29.360 Tuesday. You're going to want to set
00:25:31.120 aside some time for this
00:25:34.400 and research how each of these changes
00:25:36.400 is going to impact your app. There's
00:25:38.400 great blog posts out there about what
00:25:41.200 these changes do for a generic app, but
00:25:43.840 you really do need to work do the work
00:25:45.760 to make sure and understand how your
00:25:48.000 app's going to change in response to it.
00:25:50.720 And finally, don't wait for another fire
00:25:52.799 drill. You always think you have more
00:25:54.960 time than you do and all of a sudden
00:25:56.799 it's a late Friday night and you're
00:25:58.400 trying to figure out how to upgrade your
00:26:00.080 defaults. Maybe I speak from experience.
00:26:05.120 So, in conclusion, your upgrade isn't
00:26:08.640 complete until you handle these
00:26:10.159 defaults. Think of it like when you go
00:26:13.039 away on a trip. You spruce up your
00:26:15.840 apartment a little bit. You make the
00:26:18.000 bed. You clean the dishes. I didn't do
00:26:22.240 any of that before I left for this trip
00:26:24.320 and I should have and you should too. By
00:26:27.120 taking care of your defaults, you're
00:26:28.720 paying yourself a future kindness and
00:26:31.279 your future self will thank you for
00:26:32.880 that. And with that, I thank you for
00:26:35.600 coming to my talk.
Explore all talks recorded at RailsConf 2025
Ben Sheldon
Sam Poder
Rhiannon Payne
Joe Masilotti
Josh Puetz
Wade Winningham
Irina Nazarova
Tess Griffin
+77