Learning Rails – Upgrading Rails (Part 10)

Tue May 9, 2017 - 900 Words

Every so often a new version of Ruby on Rails is released that requires more than a few tiny changes to upgrade. Today we’ll upgrade Ruby on Rails for our meal planning application from 5.0 to 5.1.

Goals:

  • Upgrade Ruby on Rails to version 5.1
  • Explore the changes to Rails 5.1

The jump from Rails 5.0 to 5.1 isn’t a breaking change so the upgrade process shouldn’t be too difficult for us. Especially since this Rails application is rather small. That doesn’t mean that there aren’t things that we’ll want to change in our setup though.

Upgrading to Newest Patch Version

Our meal_plan app hasn’t been updated in awhile so it’s currently running 5.0.0.1 (which is admittedly a weird version number). The best practice for upgrading a Rails application is to do this in steps fixing things along the way. This application sadly doesn’t have a lot of tests so we can’t really utilize the full upgrade process, but we’ll go through the steps.

The first thing that we need to do is change our version pinning for the rails gem to match the highest patch version using “~> 5.0.0”:

Gemfile

gem 'rails', '~> 5.0.0'

To update this we need to run bundle update and let the Gemfile.lock be updated. Since we’re doing this mostly with Docker images we will use our existing image to run the bundle update.

$ docker-compose run --rm app bundle update

Once that’s finished we will need to build our image again to actually run our application using this version:

$ docker-compose up -d --build app

With the application updated to the nearest patch version and running we can run our tests and see if we get any errors or deprecation warnings:

$ docker-compose exec app rake test
Run options: --seed 239

# Running:

.............

Finished in 1.036273s, 12.5450 runs/s, 21.2299 assertions/s.

13 runs, 22 assertions, 0 failures, 0 errors, 0 skips

Our very limited test suite is working alright, but we should poke around in the application a little to see if there are any deprecation warnings that show in the logs.

Upgrading the Minor Version

Since our upgrade to Rails 5.0.2 worked just fine we’re ready to repeat the process going to Rails 5.1.

Gemfile

gem 'rails', '~> 5.1.0'

(I’ll let you repeat the steps from the previous section for yourself)

Our tests still pass, but if you try to navigate to the application on port 3000 you won’t actually see anything. Looking at docker-compose ps we can see that we’re mapping the ports correctly:

$ docker-compose ps
     Name                   Command              State           Ports
-------------------------------------------------------------------------------
mealplan_app_1   /bin/sh -c script/start         Up      0.0.0.0:3000->3000/tcp
mealplan_db_1    docker-entrypoint.sh postgres   Up      5432/tcp

Let’s use docker-compose exec to take a look at what is going on inside of our container. The main thing we want to know is what processes are running, and we’ll use ps -aux for that.

$ docker-compose exec app bash

root@8dbdfdd6f725:/usr/src/app ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   4336   800 ?        Ss   11:05   0:00 /bin/sh -c script/start
root         6  0.0  0.0  20056  2732 ?        S    11:05   0:00 /bin/bash -e script/start
root         7  0.5  0.8 1168040 71320 ?       Sl   11:05   0:01 puma 3.8.2 (tcp://0.0.0.0:9292) [app]
root        48  1.0  0.0  20248  3060 ?        Ss   11:10   0:00 bash
root        54  0.0  0.0  17500  2068 ?        R+   11:11   0:00 ps -aux

It looks like puma is bound to the wrong port for some reason. We were relying on the port defaulting properly to port 3000, but it looks like there is an issue somewhere. Let’s add the PORT variable to the .env file and restart our containers.

PORT=3000
POSTGRES_USER=coderjourney
POSTGRES_PASSWORD=abcd1234
$ docker-compose stop && docker-compose up -d

Now when we browse to our application we can see that it’s loaded just fine.

Update the Rails Files

The final step that we need to take to upgrade to this particular version of Rails is to run rails app:update. This rails subcommand will essentially take us through the files that would be generated if we created a new rails application. Our application has some tweaks that make it not quite a stock application, but it’s pretty close.

$ docker-compose exec app bash

root@8dbdfdd6f725:/usr/src/app# rails app:update

You’ll need to step through all of the changes to look at the file diff when there are conflicts and determine how you would like to handle them.

Recap

Keeping Rails up to date is a good idea to ensure that you’re not running potentially vulnerable code and there could always be performance improvements. Additionally, minor releases such as Rails 5.1.0 can come with additional features. For instance, Rails 5.1.0 comes with support for Webpack and Yarn to be worked into the frontend toolchain. I encourage you to check out all of the changes in the Release notes for Rails 5.1.0.