August 18, 2016
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 :
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.
Starting from Rails 5, each form will get its own CSRF token. This change will have following feature flag.
Rails.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
.
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:
Rails.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.
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
:
ActiveSupport.to_time_preserves_timezone
To use the Ruby 2.4+ default of to_time
, set this to true
.
belongs_to
associations by defaultIn 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:
Rails.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
.
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
:
ActiveSupport.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
.
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 :
Rails.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!
If this blog was helpful, check out our full blog archive.