Ruby 2.3 support for Rails 2.3 LTS
Rails LTS work with both Ruby 1.8.7 and Ruby 2.3. Typical web apps see a 2x to 4x performance boost by switching from Ruby 1.8.7 to Ruby 2.3.
Please find the section for your version of Rails below.
Rails 2.3 LTS
Rails LTS 2.3 has some support for modern Rubies (specifically Ruby 2.3), starting with Rails LTS 220.127.116.11. This means that upgrading a Rails 2.3 application to Ruby 2.3 will not require Rails related monkey patches.
However, upgrading will still require some effort for the majority of Rails 2.3 applications, since your own code as well as some third-party gems will most likely have compatibility issues. You should only attempt this as a somewhat experienced Ruby developer, and only if you have a good automatic test suite, or if you're confident that you can manually test your application.
So far, we managed to upgrade two medium-sized applications of our own without major issues, in 1-2 days of effort each. It did require a few dozen minor changes, and we could only do this so quickly due to a very high test coverage. The upgraded apps run at roughly twice their former speed.
Upgrade workflow overview
- If you haven't already, switch to bundler and migrate all
config.gemlines to your Gemfile.
- Switch your Ruby version to 2.3.x.
1.2.3to your Gemfile (as a top-level gem and not inside the
bundle install. Make minimal version upgrades to your gems until all can be installed. See below
config/preinitializer.rb, add a lineCopy
Encoding.default_external = Encoding::UTF_8
- In case you already were running on a Ruby > 1.8.7 and have made some Rails monkey patches yourself, remove them.
script/consoleetc. The first
requireline should look like this:Copy
require File.expand_path('../../config/boot', __FILE__)
script/consoleand fix all errors. If you get a "cannot load such file" error, try running
script/serverinstead to get a full stacktrace. See below on how to fix common errors.
script/serverand fix all errors until a page renders.
- Run tests and fix remaining errors.
Your application will probably depend on a bunch of other gems, and some of those might be incompatible with newer Rubies. The most common case are gems with native extensions that no longer compile.
You will have to check, whether these gems have an updated compatible version, can be removed, might be fixed with a monkey-patch, or have to be replaced.
An incomplete list of known incompatibilities:
date-performance-> remove this, no longer necessary
fastercsv-> no longer required, Ruby now has builtin
mysql-> we suggest updating to
mysql2 < 0.3(and changing
database.yml), but version 2.9.x should work as well
rspec-> we have a working fork of
rspec 1.3.2, see below
sass-> Current version (3.4.x) work
If you application uses Rspec 1.x for testing, the easiest way forward is to upgrade
rspec-rails to their latest RSpec 1 versions (1.3.2 for RSpec). You will also need to use our fork of
rspec, so change your Gemfile to
gem "rspec", "=1.3.2", git: 'https://github.com/makandra/rspec.git', branch: '1-3-lts'
You probably also want to use our fork or
rspec-rails which fixes a few test assertions:
gem "rspec-rails", "=1.3.5", git: 'https://github.com/makandra/rspec-rails.git', branch: '1-3-lts'
Common errors when upgrading
The following is a list of issues we encountered in our own code:
The YAML parser has changed from
.yamlfiles need to be fixed for Psych. On common case can be found in default locale files. Instead ofCopy
order: [:day, :month, :year]
order: - :day - :month - :year
You also now need to quote strings starting with
Finally, if you made use of
serializefeature, you might want to check that serialized data in your database can still be loaded.
lambdas (but not
procs) have started to check their arguments. You can no longer call a
lambdawith additional arguments, if the block does not take any.
Fix this by simply switching the offending (or possible all)
- Some methods in Ruby's standard library have changed:
object.respond_to?(:a_protected_method)used to be
true, but is now
false. You can use
object.respond_to?(:a_protected_method, true)(which will also be true for private methods, however).
object.idno longer aliases
Array("line 1\nline 2")no longer splits on linebreaks. Use
"line 1\nline 2".linesinstead if you used
Arrayfor that purpose.
Array+to_sused to work like
Array#join, but now works like
"some words".eachis gone. Use
- A few methods no longer accept symbols instead of strings (
"foo".starts_with?(:f)is now an error):
- You can potentially run into issues with String encoding. In general, everything should always be encoded as UTF-8. If you deal with binary data or lowlevel operations (like
String#unpack), you must potentially use
- Some default libraries are gone:
- Instead of
CSV. It has the same Api, but can deal with encodings.
iconvis no longer in the standard library. You can add is a gem, or replace it with
# old converter = Iconv.new('UTF-8//IGNORE', 'WINDOWS-1252') converter.iconv(text) # new text.force_encoding('WINDOWS-1252').encode('UTF-8', undef: :replace, invalid: :replace)
- Instead of
Why no Ruby 2.4?
Ruby 2.4 introduces more incompatibilities and more efforts to migrate. We might add 2.4 compatibility in the future, but consider Ruby 2.3 a good compromise between fast, modern and reasonable migration effort for now.