So, we have an existing Ruby on Rails application running under ruby 1.8.7. It would seem, “works - do not touch”! However, the transition to ruby 1.9.x for an application that we plan to develop and maintain in the future is inevitable
the following reasons:
Before the start
In version 1.9, many small changes were introduced regarding the behavior of local variables, hashes, characters, etc. The only (in my opinion) effective method to make sure that migration to the new version will pass without problems is to have sufficient coverage with automatic tests.
In other words, if you have not yet written tests (or their coverage is insignificant) - you need to write them before switching to the new version.
Most likely, you will have to make changes to the code - create a new branch in your version control system and work in it.
RVM
To manage Ruby versions we will use Ruby Version Manager (
https://rvm.io ). If you have not encountered RVM, see
http://habrahabr.ru/post/120504 . Using RVM doesn't hurt your already installed interpreter, and you can always roll back to it.
Install ruby 1.9.3 using RVM:
$ rvm install 1.9.3
This command will download the necessary sources and compile them, which usually takes a few minutes. In an ideal situation, user participation is not required. However, depending on your OS configuration, the build may require dev-versions of packages (which ones the installation script will report).
After successful installation, choose ruby 1.9.3 as an interpreter:
$ rvm use 1.9.3
To return to the system interpreter, type:
$ rvm use system
Bundler
After updating ruby, you need to reinstall the required gems with Bundler:
$ cd /path/to/app
$ bundle install
Gemes will be installed along the same path (for example, vendor / bundle), but into another subdirectory (ruby / 1.9.3 / gems instead of ruby / 1.8 / gems).
If you recorded gem versions in Gemfile, then note that very old gems may not be compatible with the new ruby.
')
Modifying the code
After installing ruby 1.9 and the necessary gems, we run tests and evaluate the scope of work on updating the code. I will give a description of a couple of common problems.
Encoding: utf-8
In ruby 1.9, the principle of working with string encoding has changed significantly (see
http://yehudakatz.com/2010/05/05/ruby-1-9-encodings-a-primer-and-the-solution-for-rails/ and
http://blog.grayproductions.net/articles/ruby_19s_three_default_encodings ). Now the file encoding must be indicated explicitly in the first line of the file. For example, if you are working in UTF-8, then at the beginning of each .rb / .rake file you need to add a line like this:
# encoding: utf-8
This can be done automatically (for example, like this:
http://leonid.shevtsov.me/ru/rasstanovka-direktivy-encoding-utf-8-dlya-ruby-1-9 or so
https://github.com/m- ryan / magic_encoding )
String.encode et al.
Several convenient functions are now available for changing the encoding of strings (see
http://ruby-doc.org/core-1.9.3/String.html#method-i-encode , etc.) - no longer need to use Iconv.
If you are using Base64, then note that the output of Base64.encode64 / decode64 is ASCII by definition, and you may have to convert it to UTF-8:
Base64.decode64('SGVsbG8sIHdvcmxkIQ==').encode('UTF-8')
Deployment
When rolling out, we will need to update both the source code of the application and the configuration of the web server. If we do not allow downtime in work, then we have several options:
- Write a fully backward-compatible code that works equally well under ruby 1.9 and 1.8 and only reconfigure the web server;
- Raise the updated project on a different IP or port and, after testing, perform a transparent substitution for the user (using a reverse proxy or DNS change).
Done!
Enjoy the results.