Tuesday, July 13, 2010

Test helpers for collections

Something that comes up often in a rails application is testing a new scope into existance on a model object. Often, I pull a collection from the scope, and want to check to make sure that the collection contains an object that I created ahead of time. The gist linked to below are a couple of naive helper methods I use for this, and you're welcome to them if you like them. Paste the "assert_contains" and "assert_does_not_contain" methods into your test_helper.rb and you're good to go.

assert_contains helpers

Friday, July 2, 2010

Panic and creativity

Nothing sparks ones creativity like an emergency. I know this intimately from my experience as a firefighter in my parallel life, but I encountered a similar situation today when I accidentally axed some data from my production database that I REALLY shouldn't have. I was playing around in the command line in production (always a brilliant idea) trying to find some elusive data to get rid of, and my practiced fingers typed ".each{|x| x.destroy}" on the end of a query that was bringing back data I really didn't want to get rid off. Suddenly my console is filling up with text like this:

[#<ProviderSchedule id: 11231, start_date: "2009-07-01", end_date: "2009-10-01", start_time: "2000-01-01 07:30:00", end_time: "2000-01-01 15:30:00", valid_flag: true, monday_included_flag: true, tuesday_included_flag: true, wednesday_included_flag: true, thursday_included_flag: true, friday_included_flag: true, saturday_included_flag: false, sunday_included_flag: false, created_at: "2009-09-09 04:34:37", updated_at: "2009-09-09 04:34:37", schedulable_id: 12092, schedulable_type: "Provider">, #<ProviderSchedule id: 39252, start_date: "2009-10-01", end_date: "2009-12-31", start_time: "2000-01-01 07:30:00", end_time: "2000-01-01 15:30:00", valid_flag: true, monday_included_flag: true, tuesday_included_flag: true, wednesday_included_flag: true, thursday_included_flag: true, friday_included_flag: true, saturday_included_flag: false, sunday_included_flag: false, created_at: "2009-09-18 17:04:44", updated_at: "2009-09-18 17:04:44", schedulable_id: 12092, schedulable_type: "Provider">...

and I'm starting to feel a little sick.  First lesson learned;  for God's sake, don't screw around in the production database.

However, what was done was done, and I needed a way to restore the data IMMEDIATELY.  Coding through a border-line panic, I quickly produced the code linked to at the following gist:

GIST!

It's quick and dirty, but it saved my ass today. If you're running Rails, and you did something as bone-headed as accidentally destroying a ton of data from the command line, this may save your life. Quickly, before you close your terminal, COPY THE OUTPUT STRING FROM YOUR DELETE OPERATION AND SAVE IT TO YOUR COMPUTER RIGHT NOW!!!!

Now, open up your command line terminal again in production (for the last time ever), copy the gist in to define the method, put the data dump inside a %Q{} stored in a local variable, and run it through the method like so along with the class object (the object which was destroyed):


=>  string = %Q{...huge long output string...}
    restore_from_destroyed_string(string,ClassName)


you'll see some output like this:


creating object 11247...true
creating object 39261...true
creating object 46838...true
creating object 72731...true
creating object 88175...true
creating object 11248...true
creating object 39262...true
creating object 46839...true

Now, wipe your forehead and pound a shot of scotch, you just averted disaster.

PS:  NEVER do that again.

patch release of quarter_time (0.3.2)

This is just a minor release of my mini-gem, quarter_time. Up until now, quarter objects have always been created using integer arguments:

quarter = Quarter.new(2010,3)


However, in cucumber tests and in rails controllers, I often have string versions of these arguments available. After casting in a couple places, I decided to make it part of the gem, so as of quarter_time 0.3.2, you can do this:

quarter = Quarter.new("2010","3")


Simple change, but useful.