Living on the Edge (or what's new in Edge Rails) #1 - API changes and PerformanceTests

As Gregg Pollack mentioned a week or so ago, I’ll be keeping a weekly-or-so column about noteworthy changes on edge Rails. This is the first time Living on the Edge (of Rails) is appearing on the official Ruby on Rails weblog, so you’ll have to bear with my short introduction.

Living on the Edge is a weekly column I used to put up on my own blog after some prodding by Gregg Pollack of Rails Envy way back in December of 2007. I used to be a rather active Rails contributor back then so it was a no-brainer. Gregg and Jason were awesome enough to feature it weekly in their podcast.

And now it’s here, so try your best to be a tough crowd so I can tune these blog posts so that they are actually useful to you – when I was blogging these on my tiny personal blog it wasn’t that vital but now the audience is significantly larger. Leave your suggestions and criticisms in the comments – they are greatly appreciated!

Anyway, there’s been a ton of new features, API changes and performance improvements in the past 2 weeks or so since Rails 2.1 was released, so rather than dumping all into one mega-post, I’ve decided to break it into 2 posts for new features/API changes and performance improvements. In this post, I’m gonna talk about some of the new features and API changes.

Minor API changes

Let’s start jump straight in with some minor API changes.

link_to now takes a block

The link_to helper now takes a block argument for those occasions when you have really long hyperlink text with variables in them:

<% link_to(@profile) do %>
  <strong><%= %></strong> -
  <span>Status: <%= @profile.status %></span>
<% end %>

Some people would find it cleaner than:

<%= link_to "<strong>#{}</strong> -- <span>Status: #{@profile.status}</span>", @profile %>

Credit goes to Sam Stephenson (of Prototype fame) and DHH for this change.

Changeset details

ActiveRecord::Base#merge_conditions is now part of the public API

Jeremy Kemper has made ActiveRecord::Base#merge_conditions a public method.

This is pretty useful if you have conditions from multiple sources or like to combine any conditions for any reason.

  {:title => 'Lucky ☆ Star'},
  ['rating IN (?)', 1..5]
=> "(`posts`.`title` = 'Lucky ☆ Star') AND (rating IN (1,2,3,4,5))"

Do note though that this merges with a SQL boolean AND only (no ORs).

Changeset details

Associations now take a :validate option

Association macros now accept a :validate option like so:

class Anime > ActiveRecord::Base
  has_many :characters, :validate => true

This tells ActiveRecord to validate the characters association when saving your Anime model – just like how :validates_associated works. The default is false, which is the current behavior in Rails 2.1 and earlier, so no need to fret. This works for all the other association macros as well (has_one, belongs_to, has_and_belongs_to_many).

Thumbs up to Jan De Poorter and Pratik Naik for this, which also fixes a nasty bug.

Changeset detailsTicket

ActiveSupport::StringInquirer and convenience Rails.env.development? methods

David Heinemeier Hansson (henceforth abbreviated as DHH – sorry!) recently added an ActiveSupport::StringInquirer String subclass that allows you to do this:

s ='awesome')
=> "awesome"
=> true
=> false

An immediate use of this is when you are checking the environment your app is running in: Rails.env is wrapped in a StringInquirer so you can use query methods like Rails.env.development? and Rails.env.production?.

Changeset details

Core extensions: Object#present? and Enumerable#many?

DHH also added some core extensions that while trivial, could make your code more readable. First up is Object#present?, which is essentially !Object#blank?

=> false
[1, 2].present?
=> true
=> false
"i'm here".present?
=> true

An Enumerable#many? extension was also added that is simply a boolean test for enumerable.size > 1:

=> false
=> false
[:just_me, 'my_friend'].many?
=> true

Object#present? changesetEnumerable#many? changeset

Declarative block syntax for writing tests

DHH was inspired by Jay Fields when he committed this bit of syntatic sugar: you can now write your tests (Test::Unit) in declarative block style like so:

test "an anime should be invalid if any of its characters are invalid" do
  # Your usual test code here.

I seldom use Test::Unit (except when submitting Rails patches) and prefer RSpec – this declarative style of writing tests is definitely more readable.

All Rails-generated test stubs now use this new syntax.

Changeset details

Performance tests

Jeremy Kemper has been hard at work optimizing and improving the performance of Rails, so it’s no surprise that he has also introduced a new type of integration test: the performance test.

You can use the performance test generator (added by Pratik in 23232a) to generate a performance test stub.

script/generate performance_test LoginStories

Running the performance test requires ruby-prof >= 0.6.1, which is still unreleased but you can get at it the development version by checking out the source and installing the gem yourself (I suggest you get Jeremy’s fork of ruby-prof for now). It’s interesting to note that with the 0.6.1 release, ruby-prof supports profiling tests cases written using Test::Unit.

Moving on… Put in some test code (request a few controller actions – whatever user story you want to test performance of) and run the test. You’ll get output like this (together with the usual ruby-prof profiling output in the test/tmp/performance directory of your Rails app):

> ruby performance/login_stories_test.rb 
Loaded suite performance/login_stories_test
LoginStoriesTest#test_homepage (32 ms warmup)
        process_time: 11 ms
              memory: unsupported
             objects: unsupported
Finished in 0.870842 seconds.

The memory and objects results are “unsupported” because I haven’t patched my Ruby interpreter for memory profiling support. You’d need certain Ruby interpreter patches to enable memory and GC profiling. I wish I could tell you more about how to do so, but I’m treading unfamiliar ground here. There are some details here on how to patch Ruby for memory profiling. I leave it for wiser folks to explain how to do this :)

Changeset details


That’s it so far for new feature/API changes in Rails since Rails 2.1 – performance improvements are coming up in the next post and I’ve also intentionally left out mention of the Rack support that has been partially merged into edge.

If there were any errors or you have any suggestions on how to make this column better, please point them out in the comments. Any info on patching your Ruby interpreter for memory profiling support is also greatly welcome. If I’ve left out anything that I’d considered not noteworthy enough but you disagree, let me know in the comments too.

Ruby Conferences and Tracks

There are several Ruby / Rails related conferences coming up in the next few months. Some of these are smaller regional conferences, and some of them are larger conferences which have their own Ruby tracks. If you know of any additional events, please comment and I’ll add them to this list.

July 21-25 – OSCON in
Portland, Oregon

This year O’Reilly’s Open Source Convention is sporting a nice looking Ruby Track with several advanced topics. Yup, this is at the Portland Convention Center, same place as Railsconf.

Cost: $1345 (sessions only)

August 1-2 – Ruby Nation in
Herndon, VA

A Washington DC Regional area Ruby conference with a great location: right next to the Washington Dulles Airport.

Cost: $175

August 8-9 – Ruby Hoedown in
Huntsville, AL

A southeast regional Ruby conference located just down the street from the Space Center (aka Spacecamp).

Cost: $199

August 15-17 – erubycon in
Columbus, OH

A conference dedicated to Ruby’s place in the Enterprise, organized by EdgeCase.

Cost: $199

September 4-6 – Lone Star Ruby Conference in
Austin, TX

A regional Ruby conference deep in the heart of Texas. They haven’t announced their speakers or opened registration yet, but I’m told they will shortly.

Cost: $250

September 20 – Windy City Rails in Chicago, IL

A day long Rails conference in Chicago covering the freshest topics in the Rails world put together by Chicago Ruby.

Cost: $99

November 17-21 – QCon in
San Francisco, CA

InfoQ and Trifork (from JAOO) put together this annual San Francisco conference with a DSLs in Practice and Ruby for the Enterprise track that any Ruby programmer would probably enjoy.

Cost: $1,695 (sessions only)

Also worth mentioning:

  • Ruby Fringe is July 18-20, but tickets are no longer available.
  • Railsconf Europe is September 2-4 as David announced last week.
  • Rubyconf is November 6-8 in Orlando, FL, but doesn’t have any information about that yet.
  • Voices that Matter: Professional Ruby Conference is November 17-20 in Boston, MA. I’m told more details will be revealed next month.
  • Merb Camp is hasn’t been officially announced yet, but I hear it might be October 11-12 in San Diego.
  • Railscamp #3 is going on this weekend (June 20-22) near Sydney, Australia, and there’s also a Railscamp UK being planned for sometime in August.
  • RuPy is this weekend (Saturday, June 21) in Omsk, Russia.

If I’ve missed any conferences, please let me know and I’ll be happy to add them.

This Week in Rails (June 16, 2008)

This is the first edition of This Week in Rails. As announced by Gregg Pollack a few days ago, this weekly column will cover highlights from the Rails community. My aim is to provide you with a status update as if you’d gone on holidays for a week. I will try to be consistent and publish once a week on Sunday or Monday. Being my first shot, I’ll rely on your feedback to verify that I’m on the right track and that this is useful to you; so please feel free to express your opinion in the comment section below.

With Rails 2.1 out, most developers are looking forward to upgrading their skills (and projects) to the latest release. If you’re one of them, I strongly recommend that you check out the second edition of Carlos Brando’s Ruby on Rails 2.1 – What’s new free e-book, which is available in both English and Portuguese, with an Italian translation currently in the works as well. You can also read Rob Anderton’s excellent overview of Rails 2.1’s improved caching capabilities, as well as its built-in support for memcached.

Last week, Phusion announced the first release candidate of Passenger 2.0 (aka mod_rails). This release introduces support for Rack, opening the door to alternative web frameworks as well. In the same announcement, Ruby Enterprise Edition was formally released. Despite the “Enterprise” label, this is a fully Open Source version of Ruby whose main claim is a reduced memory footprint on Linux and Mac OS X.

Speaking of Enterprise, Dr Nic has released version 1.0.2 of his Composite Primary Keys gem. Starting from version 1.0.0 it finally catches up with Active Record 2.1. Erubis, the fast alternative to ERB, has rolled out support for Rails 2.1 as well, in their 2.6.1 version. A week later, version 2.6.2 was released and it includes support for Ruby 1.9 as well. You can install it by running
gem install erubis or by downloading it from RubyForge.

Last week Ryan Bates put out another two Railscasts. The first is about how to contribute to Rails using Git and is, needless to say, highly recommended. The second one is in regards to substituting pagination with the effect of endless scrolling, like DZone does. As pointed out, there are plugins that do this, but Ryan’s approach builds it from scratch and is definitely worth checking out.

Other interesting articles were: a concise guide to using the Thinking Sphinx plugin (along with the pre-requisite Sphinx primer), Easy and Flexible Breadcrumbs for Rails even though they are clearly not everyone’s cup of tea, and lastly GemPlugins: A Brief Introduction to the Future of Rails Plugins.

In conclusion, two announcements were previously reported in this blog, but they are both worth repeating. The first is the release of Capistrano 2.4 and the second is that registration has opened up for RailsConf Europe 2008. The conference will be held in Berlin, Germany from the 2nd to the 4th of September. By registering before July 15th, you can save up to 150 euros.

That’s it for this week. As you can see there is no shortage of material, given that we’re such an active community. If you’d like to read more updates from the Ruby side of things, please head over to This Week in Ruby.

Capistrano 2.4.0

Capistrano 2.4.0 is now available. Capistrano is the deployment tool of choice for many Rails programmers, but can be used for much more, allowing you to automate remote tasks using a simple task-oriented framework in Ruby.

Install it via RubyGems:

  gem install capistrano

You can read the entire release announcement on Jamis Buck’s weblog.

RailsConf Europe: Registration is open!

RailsConf Europe has opened the doors for registration. The conference is returning to Berlin, Germany from September 2nd through 4th. If you register before July 15th, you can save up to 150 euros.

Considering what a blow-out success we had at RailsConf in Portland just a few weeks ago, it’s hard not to be pretty darn excited about setting up in Berlin and extending that good atmosphere across the pond. Berlin was a great spot in September last year as well.

So I’m looking forward to meeting up with more from the European Rails communities. Hopefully the very large Danish delegation will make it down this year as well :).

Two New Weekly Columns

I’d like to introduce two new contributors to the Rails blog.

First up is Chu Yeow. Chu has been putting together weekly Living on the Edge blog posts where he covers what’s been going on in Edge Rails. It seemed to me like it should be on the official blog, so expect to see his weekly updates showing up here shortly.

Secondly is Antonio Cangiano. Antonio started doing blog posts entitled This Week in Ruby a few months back which, as you might expect, cover all the significant events of the prior week. Antonio has agreed to move his weekly “Rails” stories over here, so we can all benefit from getting a summary of what’s going on in the neighborhood.

Then I should probably say a word about me, it’s not like I’m on the core team or work at 37 Signals so why am I here? I’m Gregg Pollack, one of the Rails Envy guys, and I’m here to help cover stories and help shape up the website so the real core team can focus on coding.

So if you have any Rails stories that belong on here please email me (Gregg at RailsEnvy). Worst case scenario I’ll cover it on the next Rails Envy Podcast.

Free Rails 2.1 Book

If you’re eager to learn how to use all the new features in Rails 2.1, Carlos Brando just released a free book titled Ruby on Rails 2.1, What’s New?. You can download the PDF in its original Portuguese, or its very recent English translation. This 120 page book covers everything you need to know about Rails 2.1 with many step by step examples.

You might also know Carlos Brando from the Ruby on Rails Podcast Brazil he does with Fabio Akita. If you’re a Rails developer and you speak Portuguese, definitely check out their podcast.

RubyEnRails 2008

RubyEnRails 2008 is a Dutch Rails conference happening on June 10th. They still have a few tickets left, so if you’re able to go, there’s still the option. Lots of good speakers there including Charlie from JRuby, Obie, and the Phusion Passenger guys. I’ll be doing a iChat Q&A session as well.

Rails 2.1: Time zones, dirty, caching, gem dependencies, caching, etc

Rails 2.1 is now available for general consumption with all the features and fixes we’ve been putting in over the last six months since 2.0. This has been a huge effort by a very wide range of contributors helping to make it happen.

Over the past six months, we’ve had 1,400 contributors creating patches and vetting them. This has resulted in 1,600+ patches. A truly staggering number. And lots of that has made it into this release.

New features
The new major features are:

Thanks to Ryan Daigle for the feature introductions and Ryan Bates for the Railscasts. It makes writing the release notes so much easier :).

As always, you can install with:

gem install rails

…or you can use the Git tag for 2.1.0.