When a new version of Rails comes out, one of the pain points is upgrading existing apps to the latest version.
A Rails upgrade can be boiled down to following essential steps :
- Have a green build
- Update the Rails version in Gemfile and bundle
- Run the update task to update configuration files
- Run tests and sanity checks to see if anything is broken by the upgrade and fix the issues
- Repeat step 4!
Rails 5 comes with a lot of new features. Some of them, like not halting the callback chain when a callback returns false, are breaking changes for older apps.
To keep the upgrade process easier, Rails 5 has added feature flags for all of these breaking changes.
When we create a brand new Rails 5 app, all of the feature flags
will be turned on.
We can see these feature flags
But when we upgrade an app to Rails 5, just updating the Gemfile and bundling is not enough.
We need to run the
bin/rails app:update task which will
update few configurations and also add
Rails will turn off all the feature flags
while upgrading an older app.
In this way our app won’t break due to the breaking features.
Let’s take a look at these configuration flags one by one.
Enable per-form CSRF tokens
Starting from Rails 5, each form will get its own CSRF token. This change will have following feature flag.
For new apps, it will be set to
true and for older apps upgraded to Rails 5, it
will be set to
false. Once we are ready to use this feature in our upgraded app,
we just need to change it to
Enable HTTP Origin Header checking for CSRF mitigation
For additional defense against CSRF attacks, Rails 5 has a feature to check HTTP Origin header against the site’s origin. This will be disabled by default in upgraded apps using the following configuration option:
We can set it to
true to enable HTTP origin header check when we are ready to use this feature.
Make Ruby 2.4 preserve the timezone of the receiver
In Ruby 2.4 the
to_time method for both
preserve the timezone of the receiver when converting to an instance
For upgraded apps, this feature is disabled by setting the following configuration option to
To use the Ruby 2.4+ default of
to_time, set this to
belongs_to associations by default
In Rails 5, when we define a
the association record is required to be present.
In upgraded apps, this validation is not enabled. It is disabled using the following option:
We can update our code to use this feature and turn this on by changing the above option to
Do not halt callback chain when a callback returns false
In Rails 5, callback chain is not halted when a callback returns false. This change is turned off for backward compatibility with the following option set to
We can use the new behavior of not halting the callback chain after making sure that our code
does not break due to this change and changing the value of this config to
Configure SSL options to enable HSTS with subdomains
HTTP Strict Transport Security or HSTS, is a web security policy mechanism which helps to protect websites against protocol downgrade attacks and cookie hijacking. Using HSTS, we can ask browsers to make connections using only HTTPS. In upgraded apps, HSTS is not enabled on subdomains. In new apps HSTS is enabled using the following option :
Having all these backward incompatible features which can be turned on one by one after the upgrade, in one file, eases the upgrade process. This initializer also has helpful comments explaining the features!