This one is a pretty specific hack. I’ve had the need to build mini reporting apps, using Sinatra, that aggregate data from multiple databases and produce a report. This is all fine since ActiveRecord is awesome, but I’ve always missed AR’s query caching ability.
After some digging I found that query caching is only enabled on AR’s Base connection and all other models must use that awkward Model.cache{} construct – which is annoying to use. I’ve hacked up a solution that works, although it relies on :send and instance_variable_set which isn’t very elegant or solid.
For what it’s worth, here is a “simple” way to get Sinatra to use ActiveRecord’s native query caching for more than 1 database:
Start’er up: $> open http://localhost:9292 && rackup and you should see “Hack0rific!” – now check out the log and see how AR cached and didn’t cache, it should resemble:
[2010-03-24 15:12:46] INFO WEBrick::HTTPServer#start: pid=15801 port=9292 SQL (0.2ms) SET SQL_AUTO_IS_NULL=0 SQL (0.2ms) SET SQL_AUTO_IS_NULL=0 -- enabling up per-model query caching -- MySQL::User Load (0.4ms) SELECT * FROM `user` LIMIT 1 CACHE (0.0ms) SELECT * FROM `user` LIMIT 1 ...a few more times... -- disabling up per-model query caching -- MySQL::User Load (5.3ms) SELECT * FROM `user` LIMIT 1 ...a few more times...
The one big caveat is that you need to enable_query_caching after the connection has been made (otherwise AR’s establish_connection will override your hacks) – so it needs to be in an initializer or something similar.
I’ve had great success with this in some apps, although it works a little too well so updates don’t push through when they need to. Take it for what its worth, a silly hack, and let me know how it works out for you :).
