So far, we’ve been thinking about Ajax; let’s shift now to Rails. Ruby on Rails (or more commonly, just Rails) is a full-stack MVC web development framework for the Ruby language. That’s a mouthful. Let’s break down the concepts one by one:
Full-stack means that the framework encompasses almost everything you’ll need to create a finished product. It’s perhaps a bit of a misnomer, because most applications will also require a persistence layer (a database) and a web server. But at the application level, Rails has everything needed by most projects, most of the time—there’s no need to select an additional templating system or database-mapping system.
The model represents your domain objects (such as User, Company, Post, etc.) and interacts with the database.
The controller handles user input and orchestrates interaction between the model and the view.
Web applications don’t have to be organized according to MVC—many developers freely mix all three parts. But as systems get larger, the mixed-up method quickly becomes untenable and prone to error. Code can be organized lots of ways, but MVC is the Rails way and a time-tested approach to keep your application maintainable.
A framework can be seen as a set of constraints for your program. At first, that sounds like a bad thing—why constrain yourself? But it turns out that by embracing constraints for a specific purpose, you actually enable creativity, by focusing energy on the problem at hand. The Rails framework is a set of constraints that enables effective web development.
When I was in college, I studied in Paris for a while, and I often visited cyber cafés to write friends back in the U.S. The experience introduced me to non-English keyboard layouts. Usually they were French, but I also ran into German and Spanish. The layouts of all the keyboards are similar, but just different enough to be a hassle—a few letters swapped here and there, slowing down my typing tremendously. One day, while emailing a friend, I was unable to find a way to type the letter m for the life of me.
That’s when I discovered the joys of lipograms: compositions in which one or more letter is intentionally omitted, just for the challenge. So that day I wrote a reluctant lipogram, and I’ve been fascinated with them since. Take the novel Gadsby by Ernest V. Wright, written entirely without the letter e. Here’s the first sentence:
If Youth, throughout all history, had had a champion to stand up for it; to show a doubting world that a child can think; and, possibly, do it practically; you wouldn’t constantly run across folks today who claim that ‘a child don’t know anything.’
Lipograms are about imposing artificial constraints. The interesting thing about writing them is the side effect: they force you to think more creatively about the problem of communication. When you deny yourself complete freedom in writing, it often actually allows you to express yourself better. Lipograms are an extreme example, but poetry and lyrics work the same way. Often the reason they have so much expressive power is because the writer is limited metrically or in rhyme.
Working in the Rails framework exhibits the same paradox. By embracing constraints and voluntarily giving up freedom along some axis, you enable a great deal of creative and productive power.
Ruby is an elegant, object-oriented, dynamically typed programming language, with roots in List, Perl, and Smalltalk. Its creator, Yukihiro “Matz” Matsumoto, has said Ruby is “optimized for programmer joy.” Ruby has been around since 1995 and, pardon the cliché, is quite big in Japan. But until Rails’ catalytic effect, it didn’t receive much attention in the West. Because Rails’ power is so closely tied to Ruby’s expressiveness, it can be hard to separate the two. It was no accident that David Heinemeier Hansson (or DHH, as he’s affectionately known), the creator of Rails, acknowledged his debt to Ruby right in the framework name, Ruby on Rails.
This mantra is, at heart, a story about the genesis of Rails. That genesis is Basecamp, the project-management application created by 37signals (http://www.basecamphq.com). As DHH created Basecamp, he gradually extracted infrastructure-related code out of the application code, and into the framework. The result was that the framework was shaped directly by real-world problems, rather than conceived in the abstract. The ongoing effect of this philosophy is that the Rails core developers expect additions to Rails to be drawn from real-world needs, not hypothetical ones. As a result, you won’t find a grand road map or five-year plan for Rails’ development—framework features are always extracted from applications.
For developers who have experience with other web frameworks, this idea often provides the biggest pleasant surprise. Other frameworks often require hundreds of lines of configuration code (usually in the form of XML files) before an application is usable—explicit mappings between URLs and methods, between model attributes and database columns, etc. The mantra of convention over configuration suggests that whenever possible, explicit configuration should be replaced by sensible defaults. Take database mapping, for example. Suppose you have a couple of database tables,
projects, and you’d like to model a one-to-many relationship between the database tables. The Ruby code needed to create models for those tables might look like:
class User < ActiveRecord::Base has_many :projects end class Project < ActiveRecord::Base belongs_to :user end
That’s really it! Notice that Rails uses
introspection to take the class names
Project and infers the lowercase plural forms for the table names
projects. You might also be wondering how Rails knows how to relate the two models like it does. The answer is another case of convention over configuration: it assumes that the
projects table has a column called
user_id. Of course, it’s easy to override any of the defaults that Rails assumes, as need or preference dictate—convention never replaces configuration. But following the provided conventions has a lot of benefit.
This mantra is related to the last one. Every piece of software is opinionated—it encourages (and discourages) certain ways of thinking, of solving problems, of structuring ideas. Software embodies a vision of the world. However, not all software acknowledges its opinions or strongly defines its vision. In fact, many pieces of software go out of their way to appear neutral on matters of style and practice. Rails takes the opposite approach—it has a strong vision and makes its opinions about web development very clear. Take the example above, for instance. Rails promotes the opinion that models generally ought to correspond one-to-one with database tables with plural names and a single surrogate primary key column, named
id. It’s certainly possible to work around the framework’s opinion on that issue, but it will involve more work.
Another important Rails philosophy is called the DRY principle, or don’t repeat yourself. Although it’s often misunderstood, the idea is simple: every piece of knowledge in your system ought to have one authoritative representation. Every developer knows why this is important, if she has ever had to search through a program to find all the places where one assumption is hardcoded in. But notice that knowledge is a broad term—it covers more than just lines of code. It envelops data structures, documentation, and even fuzzier concepts like intention. Mastering DRY takes effort and experience, but Rails paves the way.