Computers, Open-source, Ruby, Software

Upgrading to Rails 4

Recently, I started a new job and the first big assignment was to upgrade their software stack to a more recent version. They are running Rails 3.2 and wanted to upgrade as far forward as they can. With Rails 3.2 support gone for all but severe bug fixes, and Rails 5 due any month now, this is something they wisely didn’t want to put off.

Its a smaller company, and they have been open to a lot of my feedback and suggestions. I was basically given the reins and told to do what needed to be done to get us upgraded.

So the first task was some research, and I stumbled upon the official Rails upgrade guide pretty quickly. It nicely outlines the breaking changes. Fortunately, the big change was to strong parameters, but this can be deferred by including protected_attributes and kicking this can down the road. We will be logging what controller actions receive which parameters, instead of raising so we will have some time to collect some data before we switch over in one painful release.

The guides stressed that the test suite is critical during the upgrade. I was fortunate enough to have a project with adequate testing coverage. It wasn’t the 80% sweet spot, but it was certainly valuable at ~40%. However, the suite had fallen into disuse, so the first task was to get them back to green.

Once the test suite was green, it became a matter of KEEPING it green. Luck smiled a second time and they had an old CI server that had fallen into disuse. It was powered by CruiseControl.rb and it was little fuss to get it back up and running again. The migrations could no longer be played from the projects inception to the current time.

This is where luck stopped smiling upon me. The project did not track db/schema.rb and the migrations were not playable. The only way to get an instance of the database was to download the schema from production. Not the best practice, so I went about tracking the schema, and getting adoption of this new practice. Further complicating the schema approach was the decision to move all older migrations into subfolders in db/migrate by year (e.g. 2011, 2012, etc). This was done I found out because Textmate doesn’t like big directories. The issue is that db:schema:load isn’t recursive in its retrieval of migration versions. It took me a bit to understand what was happening, and how it was happening. After a failed monkey patch to the migrator logic in ActiveRecord, I decided to just move the migrations back into db/migrate and eliminate the subdirectories. Sorry Textmate!

Now the database could be rapidly provisioned, and I got a seed working with a minimal set of data. Back in CI I reconfigured the build script to use db:schema:load instead of db:migrate and with the green test suite, we got builds working again.

We used a utility called CC Menu to show the build status in the notification bar in OS X:

To make the builds even more visible, I discovered an integration with Slack to report the build status in our chat. . I made my own fork and added some famous movie quotes for successes and failures since I found the default messages lacking: . I didn’t think our female developers would appreciate the “you’re a stud!” message.

Back to the Rails 4 upgrade. The tests are passing in master, so I made a feature branch that will be long lived called “rails-upgrade”. I merge master in daily. The “rails-upgrade” branch will serve as an integration point for other features branches that will merge into it. The plan is to keep any upgrade related changes out of master until its time to deploy. That means separate branches, separate CI builds, and separate staging servers for manual QA.

One lesson I’ve learned is that a deprecation warning may not always be just informational. In particular, Rails 4 requires all scopes to be callable (lambdas, or procs). This was breaking the way that associations with scopes would be built: users.roles.admin.find_or_create! would previously find an associated admin record, or create it. However, in Rails 4, it fails creation because the role’s reference to user is nil. I’m not sure why, but its reproducable, and changing the admin scope on Role to a callable restores this reference back to user.

Ideally, I’d have wanted to get the test suite green before tackling deprecation warnings because I want to change as little as possible before I get back to a known good status. However, not fixing this deprecation warning was actually causing tests to fail.

Now we are down to a handful of failings tests on Rails 4. Most deal with the ActiveRecord syntax changes. Hopeful I can get these knocked out quickly. Then its on to manual QA.

In summary – get your test suite green. Keep it green. Do the upgrade and get it back to green. Then make any changes to remove deprecation warnings, keeping the suite green. The test suite is your guide during an upgrade like this.

Hardware, Software, Thoughts, Windows

Windows 7 Upgrade Isn’t All Gravy

Windows 7 logoI decided to give the gift of Windows 7 for the holidays this year. My in-laws had the unfortunate luck of replacing their old desktop with Windows ME to a new computer from Dell with Windows Vista 32-bit Home Premium. It seems they have leapfrogged to the worst OS ever released from the previous worst OS ever released. The fact they kept Windows ME running for almost five years should deserve some kind of medal.

I am running the license-unencumbered Windows 7 beta on my wife’s machine, and I have been fairly pleased with the results. On this positive experience, I took the plunge, and bought the Windows 7 Professional 64-bit upgrade. Lets break this down for a moment. There are (at least) four editions of Windows 7:

  • Home Basic
  • Home Premium
  • Professional
  • Enterprise (formerly Business?)
  • Ultimate

The good old comparison page over at Microsoft indicates that each “step up” in version encompasses all the functionalities of the lesser versions, plus some more stuff. This is a lie.

While this may be true for features, the upgrade paths seem to have been determined with a dart board (or more likely greed). Looking at upgrade paths for Windows Vista only, we can see the following:

From Windows Vista (SP1, SP2) Upgrade to Windows 7
Business Professional, Enterprise, Ultimate
Enterprise Enterprise
Home Basic Home Basic, Home Premium, Ultimate
Home Premium Home Premium, Ultimate
Ultimate Ultimate

If you were like me, you may have sprung for the extras in the “Professional” edition, but stopped short of “Ultimate” since the features it offers over Professional are pretty lame. My in-laws machine is currently running Windows Vista Home Premium 32-bit edition, and you can see that by spending more on Professional then Home Premium, I have lost my ability to upgrade. Thats right, you pay more and get less.

This has led to some extravagant solutions. The easiest is to go buy the Windows 7 Ultimate Upgrade, but refunds on opened software are non-existent. Plus, I do not want to give any more money to a company that I feel has already cheated me. Another option is to use a utility to change which edition you have an upgrade disc for. Windows 7 ships with all editions on each disc, and this tool will let you change which one you have. Alternately, you can download a digital copy of a different edition for free.

This doesn’t affect the product key though. A Windows 7 Professional key will only activate the same edition.

To upgrade from Home Professional, I would have to acquire a Windows 7 Home Professional Upgrade disc using one of the methods above. I would then have to install Windows 7 Home Professional, and then use the the Windows Anytime Upgrade to do an in place upgrade from Windows 7 Home Professional to Windows 7 Professional. Then, I can use my Windows 7 Professional product key to activate my copy.

Navigate all that, and keep in mind to watch out for 32-bit and 64-bit since they are not cross-upgradeable, or interchangeable whatsoever. The RAM requirements are even different.

So much for Windows 7 being easy.