Happy New Year! Apparently the Rails core team was not doing too much partying to end the old year: we had 35 commits hit the edge tree, and some of them involved very substantial work. Here’s my weekly overview of some of the most visible and significant changes.
In some of the first fruits of the Rails-Merb team merger, Yehuda Katz took a look at the respond_to
method, which is of course heavily used in many Rails applications to allow your controller to format results differently based on the MIME type of the incoming request. After eliminating a call to method_missing
and some profiling and tweaking, he reports an 8% improvement in the number of requests per second served with a simple respond_to
that switches between three formats. The best part? No change at all required to the code of your application to take advantage of this speedup. commit commit
If you want a preview of what else to expect from Rails 3, you might want to dip into Yehuda’s own fork of the Rails tree; I’ll be covering these changes as they make their way back into the master copy of edge Rails.
You know about dynamic finders in Rails (which allow you to concoct methods like find_by_color_and_flavor
on the fly) and named scopes (which allow you to encapsulate reusable query conditions into friendly names like currently_active
). Well, now you can have dynamic scope methods. The idea is to put together syntax that allows filtering on the fly and method chaining. For example:
Order.scoped_by_customer_id(12)
Order.scoped_by_customer_id(12).find(:all,
:conditions => "status = 'open'")
Order.scoped_by_customer_id(12).scoped_by_status("open")
There’s some further discussion of this over on Ryan Daigle’s blog. commit
There were a few changes going on in Active Record this week. A trio of commits cleaned up some behavior of associations when the :primary_key
option is specified. commit commit commit
On another front, ActiveRecord::Base#new_record?
now returns false rather than nil when confronted with an existing record. While there was some discussion of the wisdom of this change, the consensus seems to be that it can’t hurt and might make things less surprising for some developers. commit
Rails now has built-in support for HTTP digest authentication. To use it, you call authenticate_or_request_with_http_digest
with a block that returns the user’s password (which is then hashed and compared against the transmitted credentials):
class PostsController < ApplicationController
Users = {"dhh" => "secret"}
before_filter :authenticate
def secret
render :text => "Password Required!"
end
private
def authenticate
realm = "Application"
authenticate_or_request_with_http_digest(realm) do |name|
Users[name]
end
end
end
When using Active Record callbacks, you can now combine :if
and :unless
options on the same callback, and supply multiple conditions as an array:
before_save :update_credit_rating, :if => :active,
:unless => [:admin, :cash_only]
A little flurry of activity cleaned up some loose ends in our testing strategy for Rails itself. This included not running symlink tests on Windows, adding test coverage to Rails::TemplateRunner
, removing some assumptions in various tests, and getting the FCGI and sqlite2 tests working again. This is all part of a longer-term effort to make the Rails continuous integration server more useful moving forward. As you’ll see if you peek at the current build status, we’re not quite there yet, but we’re getting close.
By the way, if you want to set up your own CI server for Rails, there are instructions right in the source code.
One side effect of the changes to respond_to
is that people really liked the inline comments that make the intent of the class_eval
code clear. As a result, we now have similar comments throughout the Rails source code. For example:
def #{method_name} # def year
time.#{method_name} # time.year
end # end
If you’re just using Rails, you’ll never see these comments – but if you’re helping to maintain and improve the framework, you’ll appreciate them. commit