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 in config/initializers/new_framework_defaults.rb file.
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 config/initializers/new_framework_defaults.rb file.
Rails will turn off all the feature flags in the config/initializers/new_framework_defaults.rb file 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.
1Rails.application.config.action_controller.per_form_csrf_tokens
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 true.
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:
1Rails.application.config.action_controller.forgery_protection_origin_check
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 DateTime and Time will preserve the timezone of the receiver when converting to an instance of Time. For upgraded apps, this feature is disabled by setting the following configuration option to false :
1ActiveSupport.to_time_preserves_timezone
To use the Ruby 2.4+ default of to_time, set this to true .
Require belongs_to associations by default
In Rails 5, when we define a belongs_to association, the association record is required to be present.
In upgraded apps, this validation is not enabled. It is disabled using the following option:
1Rails.application.config.active_record.belongs_to_required_by_default
We can update our code to use this feature and turn this on by changing the above option to true.
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 true:
1ActiveSupport.halt_callback_chains_on_return_false
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 false.
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 :
1Rails.application.config.ssl_options = { hsts: { subdomains: true } }
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!
Happy Upgrading!