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)
[/ruby]

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
expect{
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)
end
[/ruby]

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.

Mavericks Upgrade and Postgres Pain

Just like the last time I upgraded my OS a mere 3 months ago (though after this week, it feels like a lifetime), when I upgraded to Mavericks last weekend so that the App Store upgrades would shut up about it, my PostgreSQL installation got hosed up. It took until today off and on to figure it out. It was similar to last time but this time I knew my Homebrew installation of PG was correct. I finally found the answer here in the comments to a previous post about a similar problem. I had to symlink an existing socket file into the location the homebrew installation was expecting it. If that sounds like I know what I’m talking about, you can forget about it because I have no idea why the socket file was in the wrong place. Still, it fixed it immediately.

I write about this only because at some point, when some other OS upgrade message beats me down, I’ll upgrade and face the same thing again. Or maybe a new problem. Who knows.

Rails, Homebrew, Postgres And The Apocalypse

Ok, it’s not the apocalypse but still. On the off chance someone ends up being in the Venn Diagram overlapping section between “broken rails environment because Homebrew upgraded Postgres” and “found my blog in Google”, this post exists. Late last week, I did a “brew update” which promptly hosed up my Rails environment locally. The error was:

rake aborted!
could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket “/tmp/.s.PGSQL.5432”?

This happened trying to migrate or prepare the database as well as on connection through the UI. That “.s.PGSQL.5432” file doesn’t exist in tmp which makes sense given the error message but the question was, did it get deleted on the upgrade or was something else the problem? After an extensive Google/Stack Overflow/crying jag, I went through the following stages of grief debugging.

DENIAL: It’s a PATH problem
This seemed promising since the error was similar. I had run into something similar when I upgraded to Mountain Lion and Postgres failed to start. Apparently I didn’t fix it completely then because when I ran “brew doctor”, I did in fact get the warning about path. So I fixed that. No love unfortunately other than removing the warning from brew.

ANGER: It’s a Permissions problem
Again, the error is similar though careful reading will see that the error message from the link above says “Permission denied” and not “No such file or directory”. My Stack Overflow habit (which is qualitatively different from my scotch habit) is to find a post that looks like a good candidate and go to the answers. This is probably a bad habit to be in since it lowers understanding and leads me on wild goose chases like this one. As it turns out, this is not a permissions problem. I confirmed this by restarting and using pgAdmin to access my local database. This was likely a Rails problem and had to be related to the homebrew update.

BARGAINING:This is a PostgreSql installation problem
This one also should have been eliminated quickly but it took a little while to put the dots together. I started digging into postgres configuration of which I know way less than I should. I found the postgres.conf file using “sudo find / -name postgres.conf”. In that, the key for the unix_socket_directory was set to “/var/pgsql_socket” and not to the “/tmp” directory my error message was indicating.

DEPRESSION: I’m going to work outside all day and not think about it
Sometimes, this is the only way to fix the problem.

ACCEPTANCE: It’s a change in where default socket files go
Not really a change and I haven’t completely grokked how this could be the problem. However, where Postgres looks for socket files is dependent on how it was built from source. I came across several references to the default being the /tmp directory. My best guess as to why this happened is that previous versions of Postgres installed via Homebrew correctly looked for socket files in /var/pgsql_socket and the latest (9.2.4 at the time of writing) does not. This Homebrew issue started me off in the right direction specifically the comments about setting PGHOST environment variable to “localhost” or setting a host in my database.yml file. However, several places have said that is a bad idea because it forces a TCP connection instead of a socket connection. Having no understanding of the ramifications of that, I read the docs on PGHOST which state that if the setting starts with a “/”, it specifies Unix domain communication instead of TCP. So I added “export PGHOST=”/var/pgsql_socket” to my .bash_profile, restarted terminal and boom, a working solution that I THINK satisfies most conditions.

Things I learned through all this: more postgres configuration, searching for files by name, a little about Unix permissions, a whole lot of patience.

Testing A Rails and Backbone App with Jasmine – Part 1 (of possibly 1 parts so far)

I’ve been playing around with Backbone.js in my Rails work but I haven’t gotten around to testing the Backbone code until today. There are quite a few tutorials out there but my basic setup took some digging around and I thought I’d document the steps I took to get a brand new Rails app in a state where I could test the JavaScript code I’m writing.

My application is going to be an ESPN Headline browser essentially using the ESPN Developer API. This API really isn’t very interesting in that it gives about zero useful information to non-paying developers but there isn’t much I can do about that. If you want to follow along, you’ll need to request an API key from ESPN. This first part doesn’t involve any actual calls to ESPN so you can skip that step for now. All the code for this app is up on Github.

I’m using the Rails 3.1.3 and the lastest Jasmine code. The first thing you need to do is install the jasmine gem by adding it to your Gemfile
[sourcecode language=”rails”]group :test do
gem ‘jasmine’
end[/sourcecode]

Once that’s done, run “bundle install”.

There is some jasmine initialization that needs to happen once the gem has been installed so run “bundle exec jasmine init”. This will create configuration files for jasmine as well as some sample tests and javascript that you can safely delete. At the time of publication of this post, Jasmine seems to still be expecting an earlier version of Rails because the generated code ends up in the “public” folder and the configuration files all reference that generated code. If you’re using Rails 3.1.3 and the new asset folders, you just need to update the jasmine.yml file in spec/javascripts/support to reference those folders. More on that in a minute.

Once we have the gem installed, we can write our first test. I’m following the convention of this guy and arranging my test code into spec/javascripts/** and my javascript into app/assets/javascripts/** where ** will match models, collections, views, etc. Fire up the Jasmine test runner by executing:
[sourcecode language=”rails”]rake jasmine[/sourcecode]
and then hit localhost:8888 in your browser. You should see something like this:

Those five tests are the sample ones that Jasmine created. A conscientious developer would delete those but I’m lazy. Plus, it makes me feel better that five tests already pass. Now, we’re ready to write our first test. I created Headline.spec.js in spec/javascripts/models to contain the test code for my Headline Backbone model.

[sourcecode language=”javascript”]describe("Headline model", function () {
beforeEach(function() {
this.headline = new Headline({
headline: "My Headline",
description: "a description",
source: "ESPN News",
byline: "Brett Bim"
});
});

describe("when instantiated", function() {
it("exhibits the attributes", function() {
expect(this.headline.get("headline")).toEqual("My Headline");
});
});

});[/sourcecode]

This is a really basic test that in actuality is testing Backbone functionality more than code but it’s a good first starting point to make sure everything is set up correctly. Refresh localhost:8888 and you’ll find out it’s not.

As you can see, Headline is not defined which is expected given that we haven’t defined it yet. Let’s do that now. Create Headline.js in app/assets/javascripts/models and add this code to it:

[sourcecode language=”javascript”]var Headline = Backbone.Model.extend();[/sourcecode]

This creates our model. Save the file and refresh localhost:8888. Surprisingly, you get the same failed test. This is because the Jasmine gem does not automatically reflect the asset structure from Rails 3.1.3. You need to explicitly specify where your files are. You can do this by going to spec/javascripts/support and opening the jasmine.yml file. There is a section for source files. You need to tell it where your source files are and add references to backbone.js and underscore.js as well.

[sourcecode language=”bash”]src_files:
– public/javascripts/prototype.js
– public/javascripts/effects.js
– public/javascripts/controls.js
– public/javascripts/dragdrop.js
– app/assets/javascripts/underscore.js
– app/assets/javascripts/backbone.js
– public/javascripts/application.js
– public/javascripts/**/*.js
– app/assets/javascripts/**/*.js[/sourcecode]

I’ve added the three lines pointing to app/assets which will inform Jasmine where to find those files. Once that’s done and the file is saved, we can refresh localhost:8888 again.

And our first test passes. We should now have Jasmine up and running for testing all our Backbone code. Stay tuned for another episode of “One Post Every 8 Months About Random Crap” where we discuss writing tank driving software using Lisp.

Web Deployment Cage Fight – 2002 versus 2011

When I first started doing web development with Visual Studio 2005, it was pretty painful work. Not only was the development itself difficult in many ways (if I say “typed DataSet” and “bloodthirsty bedbugs”, which makes you cringe more?) but the deployment of sites was often a long, tedious manual process for a site of any size. I distinctly remember having to log into my hosting provider, upload a zip file or collection of files, manually unzip or move them around and then hope that everything and the stars were lined up properly. Microsoft tried to make things easier with the Publish technology from Visual Studio but that never worked particularly seamlessly, at least not in my limited experience. On top of all that, it required considerable discipline (and a kickass source control which I’m not sure existed) if you wanted to deploy certain changes but not others.

Take a quantum leap forward into 2011. Over the last 3.5 days, I built a website to serve as my central home on the web, a place where I can aggregate my work, writing and other activities easily. I built the site in Rails, used git for source control and when it came time to deploy the site, Heroku for the hosting. To deploy my site, I had to do to things: [sourcecode language=”bash”]heroku create[/sourcecode] and [sourcecode]git push heroku master[/sourcecode] When that was done, I had a live, working test site on the internet that I could test in multiple browsers, get feedback on, etc. When I was ready to redirect my current home on the web to the new one, all I had to do was add a custom domain and Zerigo DNS add-on at Heroku, update my nameservers and presto chango, the production site was up and running.

On top of that, because branches are so painless and easy in git, I can create a new branch, work on it, merge it with the master and update the site all from the command line of my laptop. The idea of having to log into a hosting provider to upload files suddenly feels like waterboarding. If you have a significant test suite, it’s a matter of having your tests pass and then just updating your production site. Obviously, as a site grows, it won’t be quite that easy but it’s not going to get that much harder either.

The smart folks at Heroku have removed some of the major obstacles to web development so we can focus more on writing the code now and less on the administrative agony. On top of all that, for small sites like mine, the cost is negligible or non-existent. Lots of things aren’t better in 2011 than they were in 2002 (the world’s going to end next year) but web deployment, if you choose the right tools, is infinitely better in a way that’s almost inexpressible.

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.