Friday, April 17, 2009

This Week in Edge Rails

Posted by Mike Gunderloy

April 4 – April 17, 2009

Just in case you missed the news: edge Rails is waking up, with Rails 3 changes starting to show up in the master branch at Github. So there’s a lot to discuss this week. If you want some more of the technical story on the Rails 3 rearchitecting to date, check out the detailed blog postings from Yehuda Katz.

Which Branch Should I Use?

The Rails 3.0 work is being done on the master branch in the Rails repository on Github. If you want to keep up with all the latest changes, this is the branch to track – with the caveat that this is currently alpha code. It’s entirely possible to build a working Rails application using the master branch. The Rails core team is committed to keeping the master branch passing all tests, and in fact improving our test coverage and continuous integration policies are both on tap as Rails 3 improvements. But it’s important to realize that the changes to Rails will result in many plugins needing a rewrite before they will work with Rails 3 (of course, some plugins will need more updating than others). This will make Rails 3 difficult to use for full-scale production deployments for some time to come.

For existing production applications, you should be tracking the changes on the 2-3-stable branch at Github. This branch contains bug fixes and improvements to the 2.3 release code, and should continue to remain compatible with the plugins and code that you’re already using.

Should I be Submitting Patches to Rails?

Absolutely! Rails has always been a community effort and that’s not changing for Rails 3. We welcome patches for either Rails 2.3 or Rails 3.0 – please use the appropriate tag (2-3-stable or 3.0) in your Lighthouse tickets to make it easy to tell which branch you’ve tested and based your patch on. The Contributing to Rails Guide will help you through the mechanics of submitting a patch to Rails.

David outlined the overall vision for Rails 3 back in December, and that’s still the basic plan. If there’s some piece that you’d especially like to get involved with, the Ruby on Rails: Core mailing list will help you get in touch with the developers to coordinate plans – and possibly save some headaches. Most of the major pieces of work are already underway, but we know that community ideas and contributions are essential to the success of Rails 3.

Rails 2.3.x Changes

Speaking of Rails 2.3, the last couple of weeks have seen some bug fixes deployed, and one interesting piece of new functionality: ActiveRecord::Base#touch. The idea is that you get a shortcut to push the current time into the updated_at or updated_on timestamp field in a record:


@customer.touch

What makes this more than a savings of a few keystrokes is that it’s also implemented as an option for belongs_to associations:


class Order < ActiveRecord::Base
	belongs_to :customer, :touch => :last_order_update
end

With this declaration in place, saving or destroying an order object will touch the corresponding parent customer object. This can come in very handy when you’re trying to invalidate a cached copy of the parent in that situation.

commit commit

Rails 3.0 Changes

ActiveRecord::Base#touch was also added to Rails 3.0 at the same time that it went into the 2.3 branch. In general, this should be the case: new functionality from Rails 2.3 will carry over into Rails 3. The core team is working hard to ensure easy upgrades and compatibility when the time comes to make the version change. But there were a lot of other changes this week that only apply to Rails 3: that’s what the rest of this posting is about.

Module Organization

There are spots in the Rails code where there are multiple levels of inclusion and inheritance and setup. As part of making it easier to follow what’s going on, Rails 3 is introducing new depends_on, use, and setup abstractions. These can make the intent of code more obvious on reading:


module AbstractController
  module Helpers
    depends_on Renderer
 
    setup do
      ...
    end
    ...
  end
end

module ActionController
  class Base2 < AbstractBase
    use AbstractController::Callbacks
    use AbstractController::Helpers
    ...
  end
end

commit More information

AbstractController

Probably the biggest architectural change so far in Rails 3 is the introduction of the AbstractController base class. This is a new implementation of the commonalities between ActionController::Base and ActionMailer::Base, and will eventually serve as a base class for the Rails analog of Merb’s parts. The intent is not to provide code that plugins or applications will use directly, but the build a solid low-level API that other things can depend on. For example, a consumer of AbstractController will be able to implement its own path-finding logic for templates, or add additional options to the basic render method.

commit commit More information

ActionDispatch

Another internal architectural change is the introduction of ActionDispatch. A new member of the Action Pack family, ActionDispatch exists as a home for all of the various HTTP libraries and middleware that were previously stuffed into ActionController, including such things as request handling, parameter parsing, status codes, and our bundled copy of Rack. commit

Defining the Surface Area

One of the goals of the Rails 3 work is to cleanly distinguish between public API methods that plugins and application code can rely on, and Rails internals that are subject to change. For an example of this, you can look at some of the refactoring that’s been done to ActionView::Template. Here, the change is to identify the methods that aren’t used by other classes, and to make them private. This immediately makes the intended API of the class more graspable, and in the long run will help give us a contract with plugins as to how they should interact with core code. After the current surface area has been formally identified, it’s likely that it will be reduced to result in a cleaner external API. commit

AJAX and authenticity tokens

If you’ve been writing much javascript by hand, you’ve discovered the nuisance of needing to include the Rails authenticity token in your requests. A closer analysis of the issues shows that there’s no need for these tokens in AJAX requests, because the same origin policy protects them. So, Rails 3 no longer checks for those tokens on AJAX requests, and that’s one less ugly bit of javascript for you to write. commit

Test Improvements

Another area of focus in Rails 3 is to bring the internal tests up to current best practices. There are a number of spots in the existing code where the tests are less systematic than they could be – changes have been checked in with test coverage, but no one has gone through and tried to ensure full test coverage of all normal “happy” code paths. For a glimpse of what’s happening in this area, check out some of the test files in actionpack/test/new_base (the new_base code is a rewrite-in-progress of ActionController::Base). There’s also active work going on to improve our continuous integration story, and the get together some basic high-level integration tests that can exercise Rails as a whole.

Loose Ends

There are some Rails 2.3 features that are currently not implemented in master. Some changes could not be merged cleanly with the new architecture, others are being reimplemented in different ways. You’ll find some specifics in this commit message, but the missing pieces include the performance boost for development mode rendering, template recompiling in production, and some template-picking logic. The developers working on Rails 3 have indicated that they intend to get back to feature parity as quickly as possible. In fact, a first pass over the rails-dev-boost changes has already been committed.

Removed: CGI Support

Rails 3 will not support direct CGI dispatching. This was deprecated in Rails 2.3, so it should be no surprise to anyone that it’s being removed entirely. If you need to use CGI for some reason, though, remember that it’s still supported through Rack. commit