
Live from my laptop, it’s Rails Source!
After you’ve gotten the hang of Rails basics, one of the fastest ways to make the leap to black-belt Rails Warrior is to become familiar with the Rails source itself. (This remains a huge side-benefit of writing about Rails — there’s nothing like the prospect of making mistakes in public that drives somebody to extra research.)
The Rails source is arguably the most scrutinized piece of Ruby code going, so in addition to learning how Rails works, the Rails source can also help you pick up on Ruby tricks (the Rails source sold me on class << self to define a bunch of class methods), and generally give insight on how to structure large Ruby programs.
While you can get some feel for the Rails source from RDoc, there is still a lot of value in browsing the actual source files to get a feel for the connections between the different pieces in Rails.
Here’s a guide to browsing the Rails source tree (based on Edge Rails as of today, Dec 19, 2008).
Organization
The Rails source tree is split along gem lines, with top level directories for actionmailer, actionpack (containing ActionController and ActionView), activerecord, activeresource, activemodel (experimental combination of ActiveRecord and ActiveResource), and activesupport.
The railties directory contains the source file for what Rails generates when it creates a new project, as well as the standard Rake tasks (railties/lib/tasks — a very good directory to become familiar with).
Inside each top level directory, the structure is very similar to a Rails plugin. The tests are in a test directory, which often has several subdirectories organized by function. Code is in a lib directory, which typically has one top level file and one subdirectory, where the top level file just loads everything in the subdirectory. ActionPack has a directory for ActionController and ActionView, each of which has this same structure.
Within each top level directory, the first place to look is usually base.rb, as in ActionController::Base and ActiveRecord::Base. (ActiveSupport doesn’t have a base.) The other files in this directory are typically modules that support the base, but some of them are top level classes in their own right and there isn’t a real consistent convention for distinguishing the two.
Modules
The Rails code base is very dynamic, and is pretty aggressive about splitting off related behavior into modules in the name of keeping individual file lengths manageable. However, this can make it difficult to determine what modules get loaded into what classes and when. For example, ActiveRecord::Base includes a number of sub modules at the end if that file, inside a class_eval statement. (I’m not completely sure why the class_eval is necessary, actually).
Many of the modules implement the included method to implement one form or another of the common plugin structure where submodules are extended or added as needed to form class or instance methods on the class doing the including. At least one module actually opens up another class and monkey patches itself into the class. In other cases the list of included modules is generated dynamically. Despite the complexity, though, the directory structure of the files generally is a strong hint as to where the file is eventually invoked, even if the exact mechanism isn’t immediately clear.
Update 12/29 Xavier Noria and Yehuda Katz have now annotated (in Edge) all the metaprogramming in the Rails source with examples of what the actual methods will look like. See the commit.
Places To Go
Here are a few places to start looking, chosen because they are important to understanding Rails, or are interesting as code.
It’s also helpful to dig through the Rails stack in response to error messages with stack traces, which is very helpful as a view into the flow of execution through the system.
activerecord/lib/active_record/base.rb: ActiveRecord::Base. All the find methods are defined here. I particularly like pointing out the method_missing implementation that manages dynamic finder method names.
actionpack/lib/actioncontroller/routing — a directory. Somewhat hairy, but routes are pretty important in Rails…
actionpack/lib/actioncontroller/test_case.rb and test_process.rb. I’ve been reading the testing source a bit lately, and I like the use of what are basically elaborate mock objects in the controller tests. I think it helps understand the full objects, at a lower level of complexity.
activerecord/lib/active_record/named_scope.rb: Named scopes. A small file, pretty readable. Very powerful.
activesupport/lib/active_support/inflector.rb: I actually really love browsing the utility code. This is a good example of string manipulation.
activesupport/lib/active_support/memoizable.rb: Implements the memoizable meta-method. Interesting example of meta programming.

Great post!
Thanks for writing this. I also found the study of ruby meta programming t be very useful in the case of rails.
Thanks for the great post! You know what they say… to be a good Rails developer you gotta know how to actually program Ruby. To learn Ruby, you gotta look at examples of good coding…
One of my first experiences with reading the Rails code was the 1.2 router. This is like jumping into the lion’s den, but its worth it. It seems a lot of people are a little afraid of Rails’ internals, but having the courage to jump right in and read it has always proven a useful skill for myself.
Its also helpful to know that “extend self” puts class methods on instances, or vice versa. The first time I saw that construct I was dumbfounded and amused by its terse void of meaning
[...] what should we Java/GWT developers do? Taking a cue from my colleague Noel Rappin, we should Read the Source, Luke. This code reading is a triangulation excercise worthy of Bill Clinton, involving API docs, source [...]
This is helpful. I also keep abreast with new changes as they are being checked into rails core each day: http://github.com/rails/rails/commits/
You’ve rightly pointed what/where to look. I’d also love to hear from you about “how”. What I mean is static language have a good IDE support (for obvious reasons) and traversing code becomes a breeze. Since we don’t have the same ease with ruby/rails (dynamic languages), what are our next best options?
[...] Read The Source, Luke: A Reader’s Guide To Browsing Rails Source [...]
thank you for your article. i find it after to 1 month… good evening.