Upgrading A Reasonably Big Ruby Site Part 1 (of at least 1)

I’m in the process of upgrading The Sports Pool Hub to Rails 4.2 loosely following this advice As part of this, I’m upgrading all gems in my bundle file. Rspec has taken the most time as I apparently haven’t done much with it in quite awhile and large breaking changes in syntax have occurred specifically around the matchers like have_selector. My controller tests have a lot of view testing in them which is probably a big smell. When I built the site, I followed Michael Hartl’s tutorial and he was doing tests around the markup in controller tests at the time so I fell into that habit.

When I first tried the upgrade last year, Guard told me I had 327 broken tests out of 541. This caused me to check everything into a branch with a commit message of “this is never going to happen”. Six months went by and I quite happily didn’t worry too much about it. However, somewhere along the way I remembered this site actually has potential if for no other reason than to increase my ability to create something cool. Also, I built the Cry Havoc Theater in latest Rails and realized that a lot of the Rails world had passed me by on this site. So with only baseball to amuse me, I decided to try once again to upgrade.

As it turns out, those tests are largely easy to fix and revolve around two main types. The first is that some syntax had changed in the matchers as mentioned earlier. Changing a test like this:

[ruby]response.should have_selector("td", :content => "Survivor")[/ruby]

to code like this:

[ruby]expect(response.body).to have_content("Survivor")[/ruby]

is straightforward if tedious. Note that because of my occasional OCD, I also migrated from the old “should” syntax to the newer and apparently more hip “expect” syntax throughout the test suite. This caused my bourbon intake to increase slightly but not noticeably. I also upgraded all places that were looking for generic inputs like links and fields using “have_selector” to the more specific matcher “have_link” or “have_field”. This cleaned up the code considerably.

The other major type of test that changed were the ones that verified records were being saved to the database using the old lambda-do-end syntax. They looked like this:

[ruby]lambda do
post :add_pool, :id => @site.id, :include_weekly_jackpot => "1",
:current_week => 1, :current_season => ‘2011-2012’, :weekly_jackpot_amount => "1",
:pool => {:type => ‘PickemPool’}
end.should change(Jackpot, :count).by(1)

These tests weren’t broken exactly but if you’ve been reading along carefully, you know I have OCD issues when it comes to things like deprecation warnings which this test throws. So I wanted to get everything nice and clean. I had a little trouble tracking down what to do with these tests short of deleting them out of desperation. Somewhere, I stumbled onto the matching expect syntax though:

[ruby] it "adds weekly jackpot to the table" do
post :add_pool, :id => @site.id, :include_weekly_jackpot => "1",
:current_week => 1, :current_season => ‘2011-2012’, :weekly_jackpot_amount => "1",
:pool => {:type => ‘PickemPool’}
}.to change(Jackpot, :count).by(1)

Ah, much nicer.

This is where things currently stand. My site is woefully short on functional tests so I may write a few of those before I do the final code commit but so far, things haven’t been too bad.

Learning Rails (and a little Ruby)

As with most of my endeavors, I suddenly decided last week out of the blue that I needed to write a web site in Rails. I don’t really recall the thought process (which should tell you there wasn’t any) that led to this decision but given the fact that I didn’t know either Rails or Ruby past what I had learned writing WATIR scripts, I knew I needed to find a good tutorial. I reached out to my extensive (read: 82 followers) Twitter network and was pointed towards the Rails Tutorial by Karthik. Over the past 5 days, I’ve been spending a significant amount of time on learning Rails and I have to say that I have no idea why it took me this long to come around to trying it.

Quite awhile back, I dove into learning Python and the Pylons web framework and for the most part, I was happy with it. I never deployed an app using Pylons but my Python skills got to be where I could at least make things work. I enjoy the Python language but I always felt like testing was a second class citizen to a large degree. Maybe I just never read the right tutorial but tests and deployment seemed to be an afterthought. In Python’s defense, it never seemed to have the “cool kids” momentum like Ruby/Rails. And Pylons certainly has different goals than Rails given the fact that Pylons gives you some defaults but let’s you do what you want whereas Rails has the Rails Way and it’s clear you stray from it at your own risk.

But learning Pylons especially always felt like I was stabbing at zombies in the dark. I didn’t have a good mentor other than the web and while I certainly could have read code trying to figure out best practices, I’m lazy and would at least like to have some reasonable semblance of a roadmap to guide me. With Rails in general and the Rails Tutorial linked above specifically, the road map is more like a TomTom GPS system, giving you the steps you need to create and deploy applications in Rails right from the start. The emphasis on testing, source control and deployment is refreshing since I imagine that being a major headache of writing a decent sized web application in a new framework.

The use of convention over configuration, long a selling point for Rails, is wonderful. There are so many places over the last few days where I have compared my experience in the ASP.Net world to what I was learning in Rails and found the former terribly lacking. As an example, in ASP.Net MVC, named routes have to be created explicitly but in Rails, many useful named routes are created for you based on convention.

Another place Rails seems to have the advantage is database updates as you develop an application. I just went through a situation where I had to manually define how a couple of people would deal with updates to a database while working concurrently on a project. With Rails, it’s built in through the concept of migrations. So many pieces of the plumbing that you have to deal with on normal projects is just handled. I’m sure there are gotchas waiting to jump up and bite me but for someone first learning a framework and comparing it to other experiences in the past, it’s wonderfully refreshing to find so many pieces of the puzzle are taken care of for you.

On top of that, as someone who has struggled with how to coordinate programming styles and conventions on projects in the past, imagine my excitement when I learned about the Rails Way and convention over configuration. If you just do things the Rails Way, not only are certain things taken care of for you, but you can count on Rails code being comparable across projects. Imagine reading the open source code for a couple of ASP.net projects. While ASP.Net MVC has certainly moved the slider bar over towards convention, chances are the two projects would have drastically different flavors. Yet it seems to me that Rails projects would likely be reasonably similar.

Overall, I’m thrilled (obviously since I just ran through 700 words detailing my excitement) with Rails and the potential it has in my development toolbox. While it’s certainly early and I’ve no doubt been excited about things in the past, it’s encouraging to feel comfortable in a framework to some degree right from the start. Of course, major props has to go to Michael Hartl who wrote the tutorial I’m learning from. He’s done a fantastic job of laying out a good course through the material with reasons for doing things in a particular way. I intend to buy the screencasts once I work my way through the online book because I imagine they are filled with exactly the same kind of good teaching that is available in the book.