Author: Matthew

  • Drop seconds when querying MySQL timestamps

    One of the Rails apps I’ve been working on formats times as HH:MM in the view. No seconds are displayed. This is a pretty common way to format things. When doing timestamp comparisons in SQL, however, the seconds are taken into account. This is bad since it can cause discrepancies in the view.

    For example, say I have a table of records with created_at timestamps. My view displays all records with timestamps equal to or before the current time. Let’s assume the current time is 15:00:00 precisely and I happen to have a record with a timestamp of 15:00:00 in the database. The SQL comparison would work fine in this case.

    SELECT * FROM records WHERE created_at <= "2010-06-25 15:00:00"
    => 1 row in set
    

    What if the timestamp in the database is 15:00:03 though? Let’s run the query again.

    SELECT * FROM records WHERE created_at <= "2010-06-25 15:00:00"
    => Empty set
    

    Since 15:00:03 is greater than the current time of 15:00:00, the record doesn’t get returned. This would be fine if we were displaying seconds in the view, but we’re not. From the user’s perspective, the timestamp on the record is still 15:00 and should appear in the view since it’s equal to the current time. But it doesn’t.

    One way to fix this would be to handle the time comparisons in Ruby. This is certainly a legitimate option. For this particular project, though, performance was a big issue. (And we all know that Rails can’t scale.) I needed a way to continue letting the database handle the comparisons while disregarding seconds.

    The solution I ended up with isn’t ideal (it relies on a couple of functions built into MySQL) but it works fine and runs fast:

    SELECT * FROM records WHERE (created_at - INTERVAL SECOND(created_at) SECOND) <= "2010-06-25 15:00:00"
    => 1 row in set
    

    The number of seconds is extracted from the created_at timestamp and then subtracted from the timestamp. So if the timestamp was 15:00:03, MySQL subtracts 3 seconds to end up with 15:00:00.

    This solved the comparison problem for me and made my client very happy. Double win.

  • Quote of the Week: Max Beerbohm

    “Only mediocrity can be trusted to be always at its best.” — Max Beerbohm

  • Ruby Hoedown 2010

    This year’s Ruby Hoedown is happening in Nashville again on September 3rd and 4th. I’m really looking forward to attending. The quality of the talks combined with the smaller attendance size makes for some great hallway conversations. Last year’s Hoedown was at the Opryland hotel which was a stellar venue. I have seriously never seen such a large hotel. Unfortunately, it can’t be used this year due to the recent flooding. But the new venue, the Hilton Downtown, looks really nice as well. As before, the Hoedown is completely free (as in beer) and talk proposals are currently being accepted. Are you going?

    The Ruby Hoedown MMX

  • Are most of your projects one-time or maintenance?

    I’m curious about something. If you’re an independent contractor, consultant or freelancer, are most of your projects one-time gigs or do they more frequently involve long term maintenance? There is a lot of different thinking out there about how to handle ongoing work: batch it up and get it done all at once (and pay for it in one chunk too) or spreading it out over a longer period of time (the pain isn’t as severe, but lasts longer).

    Most of my projects start as one-time gigs and then evolve into ongoing maintenance work (assuming the client is pleased with what has been produced, which they generally are). I can think of only two instances where a one-time gig was just that… one-time… and didn’t involve ongoing maintenance. What has your experience been?

  • Quote of the Week: Mark Twain

    “Sometimes I wonder whether the world is being run by smart people who are putting us on, or by imbeciles who really mean it.” — Mark Twain

  • Thanks for reading!

    July 29th will mark the fifth anniversary of this blog. I realized today that I have never properly thanked you, my readers, for continuing to support this endeavor. There are so many other things you could be perusing, but you choose to patronize my humble programming blog. For that, I am grateful. Thanks for reading!

  • RubyConf in New Orleans

    This year’s RubyConf is being held in New Orleans on November 11th – 13th.

    Count me in.

    I’ve only driven through the area once so it’ll be interesting to make a longer visit. Although I’m ultimately keeping my fingers crossed for a Raleigh RubyConf one of these days. Hey, I can dream.

  • Rails 2.3.8 – an embarrassing trip

    November 30, 2009: Rails 2.3.5 has just been released. I upgrade my production Rails apps and rock on.

    February 17 of this year: RubyGems 1.3.6 is released and my apps begin suffering from deprecation warnings. They’re all over the place: when I run a test, when I launch script/console… when I sneeze.

    /Users/pelargir/Projects/teascript/config/../vendor/rails/railties/lib/rails/gem_dependency.rb:119:Warning: Gem::Dependency#version_requirements is deprecated and will be removed on or after August 2010.  Use #requirement
    

    Rumor has it the deprecation warning will go away with 2.3.6. And 2.3.6 is expected to drop any day. Yay! Problem will be solved soon… or so I thought. I begin waiting.

    May 23: 2.3.6 finally drops.
    May 24: 2.3.7 drops because of a bug in 2.3.6. What the heck?
    May 25: 2.3.8 drops because of a bug in 2.3.7. Okay, this is getting crazy.

    Was anyone else embarrassed about the 6-month delay for 2.3.6 followed by two more point releases over the span of three days? This is exactly the kind of anecdote an exec at a Fortune 500 would raise to prevent a move towards Rails and keep the company locked into Java or .NET for another decade. Ugh.

    We can do better than this.

  • Quick ‘n dirty Lindo step for Cucumber

    Lindo is great for verifying your Rails tests by opening the HTTP response body in a browser for inspection. It works with most popular testing frameworks including Test::Unit and RSpec. But what about Cucumber?

    It’s actually pretty easy to build a custom Cucumber step that triggers Lindo from your cukes. First, install the Lindo gem in your Rails app. Then create features/steps/lindo_steps.rb and insert this code:

    Then /^render the current page$/ do
      extend Lindo
      vr
    end
    

    The step can be named whatever you like best, but “render the current page” works for me. To trigger Lindo from within your cukes, simply reference the step like so:

    Given I am logged in
    When I follow "some link"
    Then render the current page
    

    When Cucumber hits the last step, the default browser window will open and the contents of the page at that step in the scenario will be displayed. This is very handy when troubleshooting why a specific scenario is failing. It’s also useful for determining what you should be testing for on a given page.

  • iPhone development

    Full Stack iPhone DevelopmentFor the past few months, I’ve been exploring the fascinating world of iPhone development. I have several application ideas and am working pretty hard on getting something to market. My first app will be free, though I hope to work up to a level where I can develop a solid paid app eventually. I’m enjoying learning Objective-C. It’s a mind bender in a lot of ways. Having to handle memory usage, for example. That gets annoying pretty quickly.

    My timing has been good since Terralien just launched its own full-stack iPhone development service last week. I’ve enjoyed developing solid Rails-based APIs for iPhones to interact with. I’m looking forward to flexing the skills I’m building on new projects. Learning is fun. The only difficulty is finding the time to learn everything I want to. It’s a never-ending pursuit.