Rajan Agaskar's blog
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!
Help
- Helper tests failing after Rails 2.2 upgrade.
A project was upgraded to run on Rails 2.2 and now has a handful of hate for helper tests. The tests in question use a stub Controller to generate a template and end up getting some nil variables. cache_classes is off. Suggestions welcome.
Interesting Things
- Pivotal Tracker Team Strength Reminder
If team members are out sick or on vacation, you can adjust your team strength settings by clicking on the blue icon at the end of the current iterations release marker. This will recalculate your current iteration velocity accordingly.

- 'flash' Partials
It is bad form to name your partials 'flash', because they attempt to populate a flash variable which has the nasty side effect of blowing away your notification array. Naming a partial 'phlash' produces no adverse effects outside of looking a little silly. 'shazzam' and 'booyakkasha' are also acceptable although somewhat less descriptive.
- Capistrano and Git
A default deploy with capistrano and git appears to prefer using the local working set instead of the configured repo (in this case, github). This may end up surprising you a great deal if you do a deploy from a machine that isn't an exact copy of HEAD. It was suggested that best practice is to deploy tags from a dedicated CI box rather than a development workstation.
- Ruby On Rails Noteworthy Applications
http://rubyonrails.org has a new design, and with it came a page of noteworthy apps running RoR. Are you a Pivotal client who'd like to see your site up there? Get in touch!
Interesting Things
Aliasing ActiveRecord reader methods
ActiveRecord reader methods are not eagerly loaded, and as such cannot be aliased using alias_method. There are a number of workarounds to this, those talked about included: calling self.define_read_methods, after which all your read methods will be loaded and available for aliasing, or you can simply define the alias instead of using alias_method.
belongs_to and foreign keys.
If you specify an alternate foreign key when using belongs to, you will have access to that id via the name of the foreign key, and not the name of the belongs_to association. It may be worthwhile allowing access to the id via the belongs_to association in order to keep consistency.
boo
BOOOO!!!!! BOOOOOOOOO!
Interesting Things
- Removing class definitions with Object.send(:remove_const, :Foo)
Sometimes it is necessary to reload or replace a stub/test class during testing (apparently rspec is particularly susceptible to this). This can be achieved using Object.send(:remove_const, :Foo) where Foo is the camel-cased name of the class. If your class is defined within a module, it may be necessary to use Module.send(:remove_const, :Foo)
Ask for help
- foo.bar.reload versus foo.bar(true)
As a point of curiosity, does anybody know when has_many relationship reloading moved from (or to?) foo.bar(true) to foo.bar.reload? The reload syntax seems preferable for readability; will foo.bar(true) continue to work in the future?
Interesting Things
- has_many_polymorphs preloads models
has_many_polymorphs will scan through the models directory for any files that include the plugin and preload them. This can cause problems if these models depend on other plugins (that have not yet been loaded) to operate correctly. The has_many_polymorphs source mentions this behavior in a comment and includes a fix:
Searches for models that use has_many_polymorphs or acts_as_double_polymorphic_join and makes sure that they get loaded during app initialization. This ensures that helper methods are injected into the target classes. Note that you can override DEFAULT_OPTIONS via Rails::Configuration#has_many_polymorphs_options. For example, if you need an application extension to be required before has_many_polymorphs loads your models, add an after_initialize block in config/environment.rb that appends to the 'requirements' key:
Rails::Initializer.run do |config|
# your other configuration here
config.after_initialize do
config.has_many_polymorphs_options['requirements'] << 'lib/my_extension'
end
end
Instead of using config.has_many_polymorphs_options, we were able to achieve the same effect by simply dropping our required plugins into the after_initialize block. If we decide to remove has_many_polymorphs in the future, the config file should still run correctly. It's worth noting that the UltraSphinx search plugin operates in a similar fashion.
- returning JavaScript in an Ajax IFrame Method (AIM) call
If you are using AIM for file uploads, you may find that any content returned to the IFrame is escaped (as if it were regular HTML). On some browsers, this occurs regardless of what the content-type is set to. A workaround is to embed any content that you don't want escaped into a comment tag; after the request completes, you can use JavaScript to retrieve the contents and optionally eval them.
Ask for help
- Ajax click_and_wait for Selenium?
assert_text_present offers a simple way to test Ajax behaviors in Selenium, as it will wait 5 seconds (during which the Ajax callback can complete) while looking for the specified text (which can be the body of your Ajax response). Another strategy with which we've had some luck is to write a custom method that will wait a specified amount of time before continuing (particularly useful if your Ajax call takes a lengthy amount of time to complete).
Interesting Things
- before_save and after_save may not perform as you expect!
Previously, returning false from before or after filters callbacks would halt the chain entirely. This is no longer the case, except with before_save and after_save -- returning false in a before_save will stop the filter callback chain and prevent a save, returning false in an after_save will stop the filter chain silently, and NOT rollback the save. This can be troublesome if you have after_save filters callbacks you expect to execute, especially if you have conditional clauses in an after_save, as they can easily return a false value where you did not intend it.
Please see Brandon Keepers' clarification regarding filters vs. callbacks below -- thanks Brandon!
Ask for help
- Bootstrapping data into an existing system?
Using migrations for one-time data inserts can be problematic (for example, when changing seed data; additionally, it's advisable to create a database from the schema.rb rather than migrations) , it can be useful to create a class that is responsible for inserting the seed data into the database. This class can be wrapped in a capistrano or rake task. The db-populate plugin is designed to aid in this task.
- Multiple Routes/One controller
It is possible to point multiple routes at a single controller, however, this situation may suggest a need for multiple controllers, possibly inheriting from a single base controller containing any shared logic. This prevents a excessive switching logic in controllers, which can help minimize the possibility of argument-related bugs.







