Dave Schweisguth in a Bottle

How many meanings of that can you think of?

Archive for the ‘Programming’ Category

Rails’ named routes considered helpful

leave a comment »

The current Rails best practice is to use RESTful routes. One nice thing about a RESTful route is that it comes with a name. Similarly, :member and :collection routes are automatically named. But sometimes you need a plain old arbitrary route, which you can then name or not as you wish. It may seem like overkill to give every route a name, especially if the route is referred to infrequently in templates. But there’s another place where you’re virtually guaranteed to need that named route again: in tests.

Read the rest of this entry »

Written by dschweisguth

May 11, 2011 at 08:36

Posted in Programming, Rails, Ruby, Testing

Do dynamic languages need more tests than static languages?

leave a comment »

Recently I made an error in a Ruby program (a Rails application) that I wouldn’t have been able to make in a Java program. I renamed a model method manually — because another class had a method with the same name, and RubyMine’s Rename Method refactoring would have renamed both methods — and although I renamed the method itself and uses of the method in the model object’s spec, I missed uses of the method in a controller and mocks of it in the controller’s spec. All of the tests passed, but the application broke. “Gee,” I thought, “if I’d had to compile everything first, that couldn’t have happened.”

Read the rest of this entry »

Written by dschweisguth

May 2, 2011 at 18:09

Posted in Programming, Testing

Avoiding extra queries in ActiveRecord 3

leave a comment »

ActiveRecord 3 introduces a new query interface based on Arel. The new query methods are more succinct than the old :conditions etc. syntax, and they’re easier to combine into complex queries. Scopes (formerly known as named scopes) are still present and useful, but there’s much less difference between a scope and a simple method that returns a query than there was before. Along with these carrots encouraging you to rewrite all your queries there is the stick of deprecation of the old syntax in Rails 3.1 and removal in Rails 3.2, so most people migrate to the new interface when they migrate to Rails 3.

Migrating GWW to the new interface went smoothly, but when I was reviewing some pages for performance recently I noticed ActiveRecord issuing some extra queries that I didn’t expect, and that weren’t necessary. Fortunately, once noticed, they were easy to eliminate.

Read the rest of this entry »

Written by dschweisguth

May 1, 2011 at 10:33

Posted in Programming, Rails, Ruby

Upgrading GWW from Rails 2, RSpec 1 and prototype to Rails 3, RSpec 2 and jQuery

leave a comment »

GWW originated on Rails 1; I upgraded it to Rails 2 last year. I’d been putting off the upgrade to Rails 3 until a bug in Phusion Passenger which breaks redirects in Apache httpd was fixed, but I want to use a database adapter which supports MySQL spatial features, and that requires Rails 3. I said goodbye to page caching until (crossing fingers) Passenger 3.0.6, made a branch and started editing my Gemfile.

Although Rails 3 has been released for more than half a year, upgrading involved many hiccups and a couple of landslides. I’d have been happy to just update my gems and be done with it, but I had to hunt around enough that it seemed worth logging what I did in case it helped someone else. I’ve kept it as short and to-the-point as I could. Although I fixed all of the deprecations that Rails 3 reported as I encountered them, I won’t mention them further, since in every case they were completely clear and fixing them only required following instructions. I’ve also left out a handful of odd little incorrectnesses in GWW which worked in Rails 2 but broke in Rails 3, since the details probably won’t interest anyone else and the fixes were obvious. Otherwise, here’s how the upgrade went.

Read the rest of this entry »

Written by dschweisguth

April 4, 2011 at 08:29

Posted in Programming, Rails, Ruby, Testing

Page caching vs. RESTful routes in Rails

leave a comment »

GWW is almost six years old. It began life on Rails 1. It’s picked up on many of the improvements to Rails made since then, but not all of them. One upgrade that remains to be done is to take more advantage of Rails’ RESTful routing. (Yes, that’s a link to the Rails 2.x docs; GWW is waiting on a Phusion Passenger bug to move to Rails 3.)

I recently added a new model type and set of page to GWW — it now explicitly tracks ScoreReports — and took the opportunity to begin using RESTful routes. It worked beautifully; I really appreciate being able to lay down a whole set of standard, named routes with so little code. But when I pushed the score reports tracking feature to production, it broke: creating a new score report (done by pushing a button to submit a form) did nothing, only refreshed to the index view with no new score report at the top. After a little head-scratching and watching the form submission with Live HTTP Headers, I realized that, like seemingly every only-in-production bug, the problem was due to caching.

Read the rest of this entry »

Written by dschweisguth

March 5, 2011 at 17:58

Posted in Programming, Rails, Ruby

Homebrewed ActiveRecord test object factories for rspec

leave a comment »

I recently took GWW from a handful of Test::Unit tests to 100% test coverage. It took some good tools (rspec and RR (Double Ruby) are both terrific), but what I didn’t do was use either of the widely used test object factory libraries, factory_girl or Machinist. I wasn’t going to use Rails fixtures, either — fixtures are just wrong — but the factory libraries rubbed me the wrong way. I could point to bits of each tool that weren’t exactly what I wanted, but the real reason I didn’t use either one was that they both seemed a little much when all I wanted to do was construct a few objects. Yes, I recognized the sound of a wheel about to be reinvented, but I went ahead anyway, and I ended up with a small amount of code very well tuned to my needs, and a couple of nice features that I don’t think the off-the-shelf solutions provide.

Read the rest of this entry »

Written by dschweisguth

March 2, 2011 at 10:01

Posted in Programming, Rails, Ruby, Testing

Controller instance variables in Rails partials

leave a comment »

A model value in a Rails partial can be a controller @instance variable or a local variable passed in by the calling template. What should it be?

Some model values must vary within a single page, so can’t be instance variables. Even when instance variables can be used, they still smell bad to the careful coder, because they have broad scope — they’re visible to every template that makes up the page. However, the controlled scope of a local comes with a cost: the template that sets it must know about it, which means more coupling between the partial and the calling template. If the partial’s locals change, so must the calling template, and perhaps its caller and its caller. For a widely-used partial, this is a lot of work. With instance variables, the caller knows nothing, and the partial can change without ripples.

So, when can you take advantage of the convenience and reduced coupling of passing model values to a partial via instance variables?

Read the rest of this entry »

Written by dschweisguth

February 22, 2011 at 18:00

Posted in Programming, Rails, Ruby

Test patterns: red-green-refactor vs. frequent committing

leave a comment »

Agile and lean principles lead to committing frequently, each commit potentially deployable to production. I’ve always been one to save my work often, and I commit often, not just whenever I finish an entire task, but whenever I’ve written enough code to justify running my tests, I do so, and they pass. This always seems like the right thing to do: it’s usually easy to break down big tasks into small, committable, deployable bits, and I can almost always point to the value in each commit, whether an implemented test, a refactoring or just a spelling fix. But I recently found myself in a situation where I realized that committing a (correct) test and its implementation that I’d just written would introduce a bug.

Read the rest of this entry »

Written by dschweisguth

February 18, 2011 at 16:46

Posted in Programming, Rails, Ruby, Testing

latin1, utf8, Rails 2.3.9 and mysql2

with one comment

GWW‘s database.yml (which originated under Rails 1.something) has never specified an encoding. We seem to have gotten away with it because mysql defaults to latin1, our database is latin1 (probably because mysql defaults to it) and the mysql gem was happy with that default. It was clear that non-ASCII characters were being handled correctly, because when using GWW one often sees Flickr usernames that contain them.

Discussions of encodings often include a statement like “start using UTF-8 now, because more and more software will assume it in the future”. They were right, and the future is now. Working towards upgrading to Rails 3, I recently updated GWW to Rails 2.3.10 and replaced the mysql gem with the mysql2 gem (which Rails 2.3.9 and later require). I’m pretty sure this is when GWW began dropping the ball on non-ASCII characters, displaying them all as question marks. I didn’t actually roll back the upgrade to prove it, and I don’t know whether it’s Rails 2.3.9/10 or mysql2. I was more interested in fixing the problem quickly — which, fortunately, it could be.

Read the rest of this entry »

Written by dschweisguth

February 16, 2011 at 11:02

Posted in Programming, Rails, Ruby

Test patterns: One test per path

leave a comment »

I’ve seen many test suites which were much less thought through and much less well factored than the code they tested. But that’s not right: Tests drive the code, so tests are at least as important as code. You should care about the quality of your tests just as much as you do the quality of your code, and refactor your tests just as vigorously as you do your code. Here, then, are some thoughts on one aspect of good test design: the One test per path pattern.

Read the rest of this entry »

Written by dschweisguth

February 15, 2011 at 12:30

Posted in Programming, Ruby, Testing