Rails Gotcha
August 29th, 2008
This is another sort of “reminder” post, mostly for myself, but maybe it’ll save someone else’s butt.
Rails offers lots and lots of nifty, terse bits of helpful code… like validations and named scopes. The gotcha is that you have to be careful to distinguish between code that gets read — and cached — at class load-time and code that will be evaluated at runtime.
To be more specific, yesterday at work, we were having problems with newly-deployed code not behaving as it had on the test server. We had added a “silencing” feature to prevent trouble makers from posting or chatting on our site. The silencings expire after a while, but we were seeing them fail to expire once we deployed to production.
Well, I tracked the problem down to this named scope to find the active silencings:
named_scope :active, :conditions => ['scheduled_end > ?', Time.now]
The problem, of course, is that the named_scope is evaluated when the class is loaded, which means that the time used in the query will be the time the class was loaded… and stay that way until the class is reloaded again.
The solution is to give named_scope a lambda:
named_scope :active, lambda {
{ :conditions => ['scheduled_end > ?', Time.now] }
}
That way the lambda is evaluated at runtime and Time.now does the right thing.
I remember back when I was starting out with Ruby that lambda was one of the concepts that it was hard for me to internalize. But this example makes it really clear: it’s just a chunk of logic passed around like data. And when the time comes its executed.
Now, this is all really pretty basic stuff; if you’ve used named scopes a lot, you probably already know all this. However, this bug slipped past us until it was actually on production. Why? Because we test on testing servers, to which all the devs are constantly deploying. So, the server gets restarted frequently, causing the time in the scope to get updated and the old silencings get expired. The code looks fine and appears to run fine. It’s an easy bug to creep in.
Actually, I found it fairly quickly because I just got burnt by a similar thing last week. I had a validation that built a regex using an array of terms loaded from the db. We had an admin page for adding terms, but the regex in the validation wouldn’t change until the class was reloaded. And then as well, the test server was being reloaded often, so the bug slipped by for a while. (Note that you can’t pass lambdas to the validation macros… had to define a method and give the macro the name of the method.)
This seems like it would be a good thing to put in a Lint for Rails. It’s strange that there still isn’t such a beast… that I’ve been able to find anyway.
Distillers Festival
August 26th, 2008
I went to the Great American Distillers Festival last weekend, and what a weekend it was. Not only was it a lot of fun, but I learned a great deal and got to sample some wonderful liquors and cocktails.
I went largely because my two brothers are big on the NW cocktail scene, going by the name Munat Brothers. And, well, I’m a Munat Brother too. I was actually included in the logo on the assumption that I’d get more involved eventually… and it looks like that expectation is coming true.
Charles and Ted put together a cocktail book called Left Coast Libations to give out at Tales of the Cocktail. It features witty banter and drink recipes from some of the hottest bartenders on the West Coast. Ted is also the fertile mind behind a blog called Le Mixeur, which revels in everything cocktail and liquor… often bathed in faux French.
They also put on cocktail parties called, of course, Le Mixeur. The fifth of these takes place on October 4th and I have promised to attend… my first Le Mixeur. I’m looking forward to it.
Anyway… the Distillers Festival. A good chunk of my time there was taken up with the mixology competition. On Saturday, this featured 20 local bartenders (2 were from Corvallis) making drink of their own devising. They had 5 minutes to set up and then 7 minutes to make enough drinks for the judges. They were judged on the drinks flavor and appearance, but also on the consistency. The competition was split into two rounds, with a different set of judges. Two finalists were picked from each of these rounds. Then, on Sunday, these four finalists were given a mystery ingredient and expected to make up a drink on the spot.
To cut to the chase, the first-place winner was Jamie MacBain from Park Kitchen and second place was Blair Reynolds from tradertiki.com. Jamie received a check for $1000 from the festival sponsors, Imbibe Magazine and Rogue Spirits. Just before the final round, the company that provided the mystery ingredient — Loft Liquers — announced that they would provide a $500 check to the first runner up. So Blair walked with that.
Well, we Munat Brothers didn’t want to be left out, so we cobbled together our meager resources and came up with a prize for the third place winner — which was Chris Churillo (sp?) from Cloud 9 in Corvallis — of $42.26 in cash. However, by the time we awarded that, we mananged to panhandle a bit more, bringing the final prize up to $77.77. I got to present the prize myself. It was great fun.
Sheesh. This is getting long and there’s so much more to talk about. Well, I’ll just quickly mention that there was much revelry and visiting of several great local bars (1001, Teardrop, Clyde Common) after the Festival on Saturday night.
Then, on Sunday afternoon before the final round of the competition, there were some talks by cocktail and liquor experts. “The History of the Cocktail” by Seattle’s well-known cocktail historian, Robert Hess, was fascinating. There was also a panel discussing the history and myths of Absinthe… short summary: all the bullshit about it being dangerous or a hallucinogen is just that: bullshit.
Sunday evening, there was a closing party at 50 Plates, with the incomparable Lance J Mayhew behind the bar. If you haven’t been to 50 Plates yet, definitely check it out; great food and great drinks.
All in all, a very fun, whirlwind of a weekend. And now, for better or worse (probably better for my taste buds and worse for my liver), I’ve been dragged into the Munat Brothers world.
Note to Self
August 5th, 2008
I don’t know why I always forget this little gotcha. This time it occurred to me, “hey, you have a blog now… stick it in your blog and then maybe you’ll find the answer faster next time”.
So here’s the deal: when you’re trying to use a Rails URL helper and you get the a NoMethodError for “nil.to_sym”, that means you’re using a plural where you should be using a singular… dummy.
Actually, I’ve always been annoyed with the pluralization crap in Rails. Computer programming was going along fine doing everything with singular nouns. But no, Rails had to make me remember yet more stuff. I think one of these days I’ll have to write a patch to Rails just to allow me to do MyModels.find :all… note the “s” there. I don’t know why my brain insists on doing this, but I do it over and over.
Oh well, I guess I shouldn’t blame Rails for my brain damage. Anyway, the above cryptic error is now recorded for posterity. Maybe it’ll help someone else out there too.