Rajan Agaskar's blog
Helps
Q: How can I plot thousands of points on a Google Map without said map being undraggable? A: It may make sense to use Google's HeatMap API after the number of plotted points exceeds 500. Other strategies are discussed here: Handling Large Amounts of Markers in Google Maps
Interesting
Using ReCSS with Sass. If you happen to be using SASS you can still make use of awesome ReCSS bookmarklets (including one by Pivotal's own Erik Hanson) by using the compass command line tool and watching your project for changes. Totally rad!
Ruby Enterprise Edition Is awesome, if you use the garbage collection tweaks. One team installed it and saw a 50% savings in their test suite running times -- over 15 minutes! Combined with parallel spec it can be a real winner. If you're on Leopard, you may need to install the version from Oct 2009, as the latest fails with a Marshall.load error on install. 2 legit!
All your RubyMine problems can be fixed! By reverting to RubyMine 1.1.1. At least if your problems are: inconsistent functionality with the merge tool, and RubyMine occasionally refusing to recognize spec files correctly. That's def!
Spring Forward this Sunday to save the daylight, and terrorize the programmers. Thanks a lot, farmers-slash-botanists. WORD Y'ALL. I'M OUT.
Helps
- Fast/Simple share widget plugins? A project was in need of a turn-key plugin to provide Digg/Twitter/Facebook links. The two suggestions were the ever-popular "roll-your-own", and pivotal's own bookmark_fu. The latter of which, if you glance downwards and towards the right, you'll see in use on this very blog! (Unless, of course, you're using Google Reader and robbing us of our ad revenue riches).
Interesting
- SpecRails Superclass Shenanigans
A Pivot found that when spec_rails is loaded, the superclass of spec suites changes to ActiveSupport::TestCase, instead of ExampleGroup (which, in this case, had a number of useful and necessary methods added to it). [1]
This carefully named plugin provides really nice sql-console-style formatting for ActiveRecord queries made from the irb console. I'm going to install it right away so I can pretend I still remember how to write MySQL queries by hand!
[1] I was working on a brilliant analogy that referenced Dick Dastardly and Muttley here, but I totally failed. Still, Wacky Races was totally rad, right? Radder than sneakily replacing superclasses, anyhow.
Interesting Things
Fixjour blows up on validations for associated models
Two Pivots experienced this problem on separate projects. The general consensus was that generating objects with correct associations can be difficult. FactoryGirl was recommended as a fixture plugin that handles this problem particularly well. It was also suggested that rolling your own object mothers was trivial (fisticuffs ensued).
timeout.rb
Timeout.rb raises an exception to kill child threads; it so happens that this exception can be caught, and possibly swallowed. This is truly a Noid to be avoided at all costs.
- UPDATE: Tests using Paperclip fail to run
When Paperclip cannot find identify in the path, it will raise an error that suggests it has been called with incorrect arguments. This is a bold-faced lie.
One Pivot remarked that these tests should really be mocking Paperclip in the first place, which seems an appropriate response to dishonesty.
Interesting Things
- fleegix.date.Date - Javascript, DST, and You
In 1895, George Vernon Hudson somehow managed to convince the world (of the Wellington Philosophical Society) that Daylight Savings Time was a good idea.[1] Hudson, an amateur entomologist, was motivated by his desire to look for bugs after work.[2] Sadly he did not forsee that determining DST for multiple regions using JavaScript would be a non-trivial task.
Javascript provides some rudimentary timezone support with Date.parse, but does not automatically apply daylight savings time, in other words:
Date.parse('Sep 9 2009 11:00:00 PST');
and
Date.parse('Sep 9 2009 11:00:00 PDT');
return different timestamps. fleegix.date.Date (a plugin for the fleegix.js library) lets you express the timezone as a region string, automatically taking into account whether or not that region observes Daylight Savings Time (by using Olson files), and providing the same interface as the native Javascript date. This means you can get an proper timestamp with the following:
new fleegix.date.Date('9/9/2009 11:00:00', 'America/Los_Angeles');
This is arguably more useful than Daylight Savings Time itself.
- RightScale errors
Two Pivots experienced an issue where RightScale was caching their connection to Amazon upon creation. This led to the connection start time parameter getting further and further out of date until Amazon failed to accept the upload with a 'Request Time Too Skewed' error. No workaround was discussed, but it was roundly decided that any error with the word "Skewed" in it is pretty awesome. [3]
[1] Well, according to Wikipedia, so it might as well have been Ron Paul for all we know.
[2] aaaaaand rimshot.
[3] Not really.
Interesting Things
- Pivotal Core Bundle - Deprecations deprecated!
Two Pivots heroically removed some deprecated extensions and rake tasks from the Pivotal Core Bundle. Do not be surprised if your favorite code jams (like cancel_default_validates_associated class method) disappear next time you pull.
- Move files fast!
Some lucky pivot discovered that
mv file.tgz *will move all files in the current path into the last file or directory it can find.
If for some reason you do not want this to happen, it is recommended that you always specify a destination when moving files.
To help you remember this protip, here's a totally worthless analogy that involves automobiles: would you get into a cab without telling the driver where you wanted to go?
No, you would not, because he would take you to IHOP, and you hate pancakes. You wanted to go to Waffle House, which is unfortunate, because the nearest Waffle House is in Nevada.
Harlan Wood, one of our client developers, has founded a monthly hackfest project that may be of interest to the Rails community. From Harlan:
"I am putting together a monthly Hackfest for the Light, kicking off in late January. The idea is to put some of the great skills in our community to use on socially responsible software projects of any sort, with a preference toward open source, ruby/rails, and great testing, but open to just about anything. Participants will introduce projects of interest, or just bring their coding/UI skills, and developers and designers will work together on whichever projects inspire them.
An example project I'm working on is a creative collaboration remixing engine -- like a github for creative commons licenced creative works. More on that here: http://enlightenedstructure.info/pub/WikiDragon.
I've created a meetup group ( http://www.meetup.com/Hackfest-for-the-Light/ ) -- this is the best way to stay in touch if you're interested.
H@rlan Knight Wood"
Interesting Things
- Ruby Hash is really, really, really fast
If you're building a data structure and you need it to be perfomant, Ruby Hash comes highly recommended from Steve Conover. If you're doing a dance and you need it to be awesome, I highly recommend the Robot. Or maybe the Cabbage Patch.
- Counter cache, fixtures, and invalid data
Invalid counter cache data can cause unexpected behavior. For example: size() returning a bad count or associations asserting they're empty when they aren't. In this case, the invalid counter cache data was caused by bad or missing fixture values, a situation that was not caught out by the debugger. With this in mind, it may be useful to resort to puts/p statements if you suspect the counter cache is the source of the problem.
- Count or Size methods may return incorrect values from associations or named scopes using GROUP BYs
When calling 'count', or 'size' on an association, Rails replaces the select of the actual query with a COUNT(*), and strips GROUP BY statements. This can cause the returned count to differ from the actual number of records. A simple (and expensive) workaround is to use .length, which will force the association to be loaded and then return its count. A better method is to pass a :select value to count which selects a COUNT(DISTINCT(foo)) where foo is the column you are grouping by. It is worth nothing that COUNTing DISTINCT records is much less of a performance hit then actually returning their values, so the resulting query is faster than you might expect.
- first and last on has_many associations
This has been previously mentioned in this space, but as we're on the topic of unexpected ActiveRecord behaviors, it's worth reiterating. If you have model Foo, which has many Bars, calling foo.bar.first will always go to the database. This means, for example, that the following statements will not have the expected result:
foo.bar.first.some_value = 'baz'
foo.bar.first.save
You would normally expect this to set some_value on foo.bar.first to 'baz' and then save it, but the foo.bar.first object that has some_value is blown away by the foo.bar.first.save statement, which again retrieves the first object from the database (and then saves it). last behaves in a similar manner. A workaround is to always load the results of first or last into an variable and then work with it. In other words:
my_foo = foo.bar.first
my_foo.some_value = 'baz'
my_foo.save
For a much more thorough treatment of this subject, please see Frederick Cheung's post First, foremost, and [0].
ActiveRecord::BaseWithoutTable is very handy for when you want ActiveRecord validatioons on a model that does not have a corresponding table (for example, a feedback form).
Interesting Things
- Net::HTTP is slow
Recommended alternatives: Curb, httpclient, rfuzz.
Please see Steve Conover's writeup for more details.
- Marshall Dump/Load encoding issues foiled by Base 64.
When storing to a string via marshal_dump, it can be handy to encode to Base 64 first. The same string -- once marshal-loaded and Base 64 decoded -- should be free of any encoding and/or escaping errors. Is there anything Base 64 can't do?*
* the answer I am looking for here is "win a knife fight against tigers."
Interesting Things
- Rails 2.2 Exception Notifier
Setting the Exception Notifier sender address outside the post load block in Rails 2.2 can cause long load times. Like, 6 minutes long. Why? GLOBAL WARMING! Which is to say we aren't sure, but it probably involves class pre-loading*.
* The natural corollary being, of course, that class pre-loading causes hurricanes.
Help
- Functional tests running slowly after upgrade to Rails 2.2
A project upgraded to Rails 2.2 which was previously able to complete its functional suite in under 300 seconds now takes a leisurely 6000 seconds to finish. Speculation about possible causes is welcomed. Meanwhile, I suspect ghosts.
UPDATE: apparently the functional tests were running slow due to memory swappage (the memory swappage, in turn, caused by ghosts, no doubt).
Interesting Things
- Rails 2.2 may break Selenium tests
Rails 2.2 continues its reign of terror by using 'secure' HTTP-only cookies by default that cannot be read or set via javascript. This can cause selenium tests that attempt to logout by deleting the client-side session cookie to fail. The fix is simple enough; add :session_http_only => false in the config.action_controller.session hash in environment.rb. Or, to simply turn it off for your testing environment (which means you'll still get the benefit of secure cookies in production), you can add ActionController::Base.session_options[:session_http_only] = false in your test.rb file. Alternatively, you can add explicit logout calls to your selenium tests, but expect these to add considerable time to your selenium suite.
- FixtureScenarios and slow test suites
A pivot installed FixtureScenarios on a project and found that the addition of the plugin alone (with no configured fixtures) doubled the time the project's test suites took to complete. FixtureScenarios are now dead to Adam. Dead!
- No Pivotal Breakfast tomorrow
Karen Tsui and Ling-Wen Chang tirelessly prepare the world-famous Pivotal breakfast each day and generally make the San Francisco office an awesome place to work. They're finally taking a much deserved break tomorrow, so now is a wonderful time to publicly recognize their much appreciated work. Thanks, and happy holidays!







