Get a quote!

Blog

Using Relational Data Responsibly

Written by Jared Haworth on

Every Christmas, my father sends gift assortments from Swiss Colony to family members, friends, and former business associates. Last month, he shared with me an interesting story about how Swiss Colony handles repeat customers; which he gave me permission to retell here, because I think it’s a great example of a non-technical company using modern technology effectively.

He started out telling me about a woman who used to work for him 18 years ago, someone whom he has kept in touch with over the years, exchanging a few letters annually. He knew that she had moved recently, but had not yet received her new mailing address. However, when he received his most recent Swiss Colony catalog, he noticed that her address had been updated. He was suitably impressed.

One of my former jobs required me to send periodical mailings to a nationwide group of photojournalists, an activity that probably gave me more insight into business-based bulk mailing than any web application developer would ever care to have. But, it did leave me with an answer as to how her information was likely updated. It would seem that the company runs it’s entire recipient database through an automated service, such as Verimove, in order to keep their mailing address data fresh.

In addition to providing repeat customers with the list of all the recipients who had received gifts the previous year, they also include the previous year’s order for each recipient. It’s a refreshing change of pace from those companies that vacuum up a great deal of information about their customers but then don’t turn it around and use it effectively. Swiss Colony offers, even for it’s mail-order customers, the benefit of relational data.

Taking this a step further for the world of web development, this sort of information can be ideal to use as part of a ‘hook’ strategy to drive return traffic to an application. Instead of just emailing existing users to tell them about new products or services you provide, offer them value by doing a little bit of analysis on the relationships they already have in your systems, and making their experience more convenient.

Advanced YAML Fixtures Gotchas

Written by Jared Haworth on

I was very excited to use the new Advanced YAML Fixtures introduced in Rails 2.0, so I set about updating my code in an Edge Rails application I’ve been working on for the past year or so. There are a few caveats in using the new fixture styles, though.

The Fixtures are introspective, so if you’ve overridden the default name of an association in your model, you’ll need to use that new name in your fixture. With the following code,

class Worker < ActiveRecord::Base
  belongs_to :status, :class_name => 'WorkerStatus', :foreign_key => 'worker_status_id'
  ...
end

The key for worker_status: should actually just be status: in the workers.yml fixture file.

The larger problem I encountered was in using a mix of IDs and fixture record names. I use a testing framework, TestRig, which was written by Mike Clark and Dave Thomas for the Pragmatic Studio. The TestRig framework takes in ID parameters of fixtures in the database, and loads them accordingly. This falls apart with the new status: full_time style of declaring relationships in fixtures, because the former relies on a ‘known’ ID, and the new style generates a fairly random ID instead. This leads to a bunch of broken relationships throughout the test suite.

According to the API documentation, the generated ID is constant, so I could discover that ID and use it in the TestRig calls which require an integer key, but then I’ve essentially lost all benefit of using the Advanced YAML Fixtures, and added some crazy complexity to my tests as well.

Learning RSpec

Written by Jared Haworth on

The end of 2007 has brought about some exciting changes for me, most notably a new job with Education Revolution. To try and ease the transition during a stressful holiday season, I gave myself a week off between jobs, which left me with a bit of unexpected time on my hands between Christmas and New Year’s. I decided to make the most of my time off and try to learn RSpec.

RSpec is quickly becoming a darling among some of the visionaries in the Rails world. With the release of RSpec 1.1, which brings easy integration between Test::Unit style testing and Behavior Driven Development using RSpec, it seemed prudent to try it on myself and see how it fits.

On the whole I really like the idea of specifying behaviors instead of assertions, especially when coupled with doing some design-driven development. As a developer, having both a clear set of expected behaviors and a set of slides which show the application in a near-finished state, it removes a lot of the guesswork which had been plaguing me on previous projects. Also, hearing Adam Williams and John Long talk at November’s Raleigh.rb meetup about doing top-down testing (starting with integration tests, then drilling down to functional and unit tests merely to handle edge cases) has turned my opinion of Integration tests on it’s head.

Having come from a metaprogramming-driven Test::Unit background using Mike Clark’s TestRig framework, RSpec felt like a lot more testing code. And indeed, my rake stats seems to support that, showing a 1:2.8 ratio for my training project. Finding help with RSpec has been tricky, though. There are some really great contrived examples on the RSpec homepage, but I had trouble finding more information on how to deal with presenters, nested resources, and HTTP Basic authentication. I want to show off two solutions that I cobbled together out of solutions found online.

The first problem I encountered was in dealing with the save! method in ActiveRecord. My controllers typically use the save! coupled with a rescue statement for ActiveRecord::RecordInvalid, like so:

class WidgetsController < ApplicationController

	def create
		@widget = Widget.new(params[:widget])
		@widget.save!
		respond_to do |format|
			format.html { redirect_to @widget }
		end
	rescue ActiveRecord::RecordInvalid => e
		respond_to do |format|
			format.html { render :action => 'edit' }
		end
	end

end

Most of the RSpec examples I had come across show something like this (excerpted from Testing Controllers with RSpec):

def do_create
  post :create, :menu_item=>{:name=>"value"}
end

it "should save the menu item" do
  @menu_item.should_receive(:save).and_return(false)
  do_create
end

The problem being, using save! doesn’t return false on failure, it raises an exception. Fortunately, the answer was available on the RSpec-users mailing list. Now my widet_controller_spec.rb contains the following:

it "should fail to save the widget" do
  @widget.should_receive(:save!).and_raise(ActiveRecord::RecordInvalid.new(@widget))
end

The second major stoppage I encountered was dealing with HTTP Basic authentication. The application I was building didn’t require a huge complicated account/password structure, it just needed a few protected pages available to a single administrator.

class ApplicationController < ActionController::Base

	before_filter :authenticate

	def authenticate
	  authenticate_or_request_with_http_basic do |username, password|
	    username == 'jared' && password == 'secret'
	  end
	end
end

Suddenly, all my controller specs for actions lying behind that authenticate filter were failing. The fix lies in stubbing out the method using the controller local variable in the spec.

describe WidgetsController do

  describe "with successful admin login" do
    before(:each) do
      controller.stub!(:authenticate).and_return(true)
    end
		...
	end
end

Of course, I still need to come back and write an integration test which will address both the success and failure states of the authenticate method.

All in all, I’m very impressed with RSpec, and I can see why it’s picking up such a following. I’m definitely going to play around with it further, but I’m not quite ready to say that I’m going to switch all my projects over; one important factor to consider is future code maintainability. The pool of talented Rails developers is small enough to begin with, adding the further requirement of finding a Rails developer who is also versed in RSpec limits that result set even further.