This article summarizes some important points from David Heinemeier Hansson’s keynote at RailsConf Europe 2007 in Berlin. Last year, DHH brought us the whole REST way of thinking which I immediately named normalization, but that term didn’t really catch on.

David Heinemeier Hansson
© 2007 Pinar Ozger

This year, DHH noted that he up until now had started all his previous keynotes about Rails celebrating how “freakin’ fantastic we are”. For this keynote, he thought – with Rails being well within in its third year in existence – that it was time to perhaps be happy with what we have.

He explained that new things tend to go through certain phases: First they ignore you, then they laugh at you, then they fight you, and then you win – … and then what? “Ruby on Rails went through these phases way too fast”, DHH said, “I was having a lot of fun going through these phases; I’m kind of sad it is over.”

For the last couple of years, David and the Rails community has pushing new concepts; Convention over configuration, AJAX and REST, but these focal points were adopted very fast, so there is no big cause to fight for right now. That leaves Rails 2.0 in a really weird spot, since it won’t have any groundbreaking new concepts.

This is not a bad thing, though, DHH stressed. “Even though [the lack of a great cause] is an off-switch for me, it’s not about me anymore”, he said. “Rails are moving from big revolutions to tiny evolutions” – a statement that was underlined when David went on to demonstrate new features in Rails; features that were definitely more tiny evolutions than big revolutions.

But before we get to the Rails 2.0 code examples of the keynote, let me just mention something that was news to me: The new policy for how to get a patch into Rails, also known as Report #12. The idea is basically that you, once you have written a patch and submitted it to the Rails trac, should get three other Rails developers to check out your patch, verify that your tests run, and then add a “+1″ in a comment in trac. Once you have your three “+1″‘s, you tag your patch with the keyword “verified”, and the patch will appear in Report #12: Verified Patches. The core team should then – theoretically – be able to very fast to accept the patch into Rails.

Moving on to the, in my opinion, most interesting part of the presentation: What’s new in Rails 2.0 – show me the code! Migrations has been updated to support a new syntax known as “sexy migrations”, which basically allows even shorter and more readable migrations by grouping fields of the same type:

create_table :blogs do |t|
	t.string :title, :subtitle
	t.text :body, :description
	t.integer :category_id
	t.timestamps # Adds created_at and updated_at fields
end

Notice how another evolutionary improvement has been sneaked in: Tired of always adding created_at and updated_at timestamps to most tables, a timestamps method has been added as a shortcut. Also this new syntax, including the timestamps, is now standard in the model and scaffold generators.

A small, but to me significant improvement has also found its way to Rails 2.0: You can now create the needed databases with a rake command. By running this command, all referenced databases in your database.yml will be created:

rake db:create:all

Another interesting, and perhaps generally quite invisible improvement, is that session data are now stored in a encrypted cookie instead on each server, which makes it easy to partition applications across multiple servers without having to put session data in the database. This requires, of course, the session data to be quite compact (storing id’s, not entire objects), as a cookie can contain 4 KB of data the most.

My favourite point of DHH’s keynote was his solution to the common pattern of a resource, which you both need to display to the common user (usually index and show) and to the admin user (usually index, new, create, edit, update and destroy). The normal RESTful solution to this leaves with a problem, because we are only allowed one index action, and we need two; one for the common user and one for the admin user. Also, the admin actions will usually have a different layout than the common user actions, and they require some kind of authorization.

The solution is to used RESTful namespaced routes, referring to two different controllers with the same name, but in different namespaces. To use DHH’s eternal blog example:

./script/generate controller posts # => /controllers/posts_controller.rb
./script/generate controller admin::posts # => /controllers/admin/posts_controller.rb

Now we have two different controllers working in the same model; Post, but offering different actions, layouts, authorization and so on. This nice thing about this solution, is that it is very easy to understand and fits well into the Rails structure. The catch is that we have two controllers with the same name, so we need to explicitly express the namespace when referring to the admin controller:

form_for([:admin, post]) do |f|
	...
end

DHH also pointed out that HTTP authentication is a perfect way of doing authentication for administration pages (which I’d already realized). You don’t really need nice-looking form-authentication and remember me checkboxes for that, and it is so very easy to implement with Rails 2.0:

# In a controller or module shared between admin controllers
before_filter :ensure_administrator
def ensure_administrator
	authenticate_or_request_with_http_basic('Blog admin') do |username, password|
		username == 'dhh' && password == '123'
	end
end

A very visible change in Rails 2.0 is the naming of views. The .rhtml, .rxml etc. file endings has been discarded to replaced by the form [name].[mime-type].[renderer]. This leaves the road open for file names such as:

  • index.html.erb
  • index.xml.builder
  • index.html.liquid
  • index.iphone.erb

The last example needs a little additional configuration, since iphone is not a “real” mime-type, but we can easily make Rails treat it like such:

# In mime_types.rb:
Mime::Type.register "application/x-iphone"

# In application.rb:
before_filter :adjust_format_for_iphone
def adjust_format_for_iphone
	if request.env["HTTP_USER:AGENT"] ~= /iPhone/
		request.format = :iphone
	end
end

# In specific controllers
respond_to do |format|
	...
	format.iphone do
		render :text => 'Hello iPhone', :content_type => Mime::Html
	end
end

Notice how content_type must manually be set to Mime::Html, as the iPhone browser – as well as any other browser – doesn’t recognize our fake x-iphone mime-type, and Rails will always default to respond with the request mime-type.

My second favourite point was about the “new” debugging support in Rails 2.0. As I understood it, the well-known ruby-debugger library has been baked into Rails 2.0, so that we write debugger instead of breakpoint, and need to start the server with a --debugger prefix (./script/server --debugger) to enable these breakpoints. This debugger also support more advanced commands such as “cont” (continue), “list” (view current code) and “up” (step out).

David Heinemeier Hansson rounded off his keynote by announcing the release of a Rails 2.0 Preview Release (how Microsoft-ish does that sound?) either during or shortly after the conference.

You can download my full notes from the keynote here.

UPDATE: My other notes from RailsConf Europe 2007 are now available.

Bookmark and Share