Friday, January 20, 2012

Rails 3.2.0: Faster dev mode & routing, explain queries, tagged logger, store

Posted by David

So we didn’t quite make the December release date as we intended, but hey, why break a good tradition and start hitting release targets now! In any case, your patience has been worldly rewarded young grasshopper: Rails 3.2 is done, baked, tested, and ready to roll!

I’ve been running on 3-2-stable for a few months working on Basecamp Next and it’s been a real treat. The new faster dev mode in particular is a major step up over 3.1.

Do remember that this is the last intended release series that’s going to support Ruby 1.8.7. The master git branch for Rails is now targeting Rails 4.0, which will require Ruby 1.9.3 and above. So now is a great time to start the work on getting your app ready for the current version of Ruby. Let’s not hang around old versions forever and a Sunday like those Python guys :).

There’s a v3.2.0 tag on Github and we of course we still have the 3-2-stable branch as well. You can see all the glorious details of everything that was changed in our CHANGELOG compilation.

For documentation, we have the 3.2 release notes with upgrade instructions, both the API docs and the guides have been generated for 3.2 as well, and there’s a brand new 3.2-compatible version of Agile Web Development with Rails. A smörgåsbord indeed!

Note: If you’re having trouble installing the gems under Ruby 1.8.7, you’ve probably hit a RubyGems bug with YAML that’s been fixed in RubyGems 1.8.15. You can upgrade RubyGems using “gem update —system”.

If you can’t be bothered with the full release notes, here’s a reprint of a few feature highlights from when we did the first release candidate:

Faster dev mode & routing

The most noticeable new feature is that development mode got a ton and a half faster. Inspired by Active Reload, we now only reload classes from files you’ve actually changed. The difference is dramatic on a larger application.

Route recognition also got a bunch faster thanks to the new Journey engine and we made linking much faster as well (especially apparent when you’re having 100+ links on a single page).

Explain queries

We’ve added a quick and easy way to explain quieries generated by ARel. In the console, you can run something like puts Person.active.limit(5).explain and you’ll get the query ARel produces explained (so you can easily see whether its using the right indexes). There’s even a default threshold in development mode where if a query takes more than half a second to run, it’s automatically explained inline — how about that!

Tagged logger

When you’re running a multi-user, multi-account application, it’s a great help to be able to filter the log by who did what. Enter the TaggedLogging wrapper. It works like this:

Logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
Logger.tagged("BCX") { Logger.info "Stuff" } # Logs "[BCX] Stuff"
Logger.tagged("BCX") do
  Logger.tagged("Jason") do
    Logger.info "Stuff" # Logs "\[BCX\] \[Jason\] Stuff"
  end
end

Active Record Store

Key/value stores are great, but it’s not always you want to go the whole honking way just for a little variable-key action. Enter the Active Record Store:

class User < ActiveRecord::Base
  store :settings, accessors: [ :color, :homepage ]
end
 
u = User.new(color: 'black', homepage: '37signals.com')
u.color                          # Accessor stored attribute
u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor