Wednesday, January 03, 2007

Rails: Enterprise Ready

"Is Rails Enterprise Ready?"

I've avoided the question since I started working with Rails. In fact, if pressed, I previously would have stated that Rails wasn't enterprise ready. Claiming that it isn't ready is much easier than proving that it is.

But, now things are different. I'm working on a development team with 14 coders. Our application has it's own database and also integrates with 2 other legacy databases. Our application also integrates with external services via SOAP and RESTful web services. The application currently has a unit test suite that consistently runs in less than 1 second. It also has a domain model that is separated from the UI by inserting a Presenter layer.

Did Rails handle this type of environment out of the box? No. However, Ruby + Rails made it easy to extend Rails where it was necessary. Since I was able to easily extend the framework to my needs, I'm now completely comfortable stating that Rails is "Enterprise Ready". In fact, out of the box Rails solves about 80% of the problems I have, which is better than most "Enterprise" software I'm usually working with.

Out of the box, Rails expects you to be working with one database that you have full control over. Sometimes, life isn't that easy. Luckily, back in January of 2006 Dave Thomas wrote a blog entry on how to create and share database connections to additional databases. Using this article as a reference, we were able to fairly easily integrate our application with our database and the 2 legacy databases we needed to both read and write to.

Connecting to external services was also an easy task. We wrote a few Gateways that took advantage of Net::Http. These Gateway classes took our domain objects, mapped them to valid request objects for the external services, and formatted the result to our needs.

We've spent a lot of time ensuring that our test suite is quite solid, yet ran as fast as possible. The first step was removing access to the database from the unit tests. After that, we also looked at allowing ActiveRecord::Base subclasses to be tested without needing access to the database. The result is a sub 1-second unit test run that provides greater than 80% code coverage.

We also spent a fair amount of time on creating Presenter classes that sit between the UI and the Models. In our application several of the pages contain more than one domain model. For example, a page may collect a billing address and credit card information. Instead of creating several models in the controller we create one presenter instance that collects and validates input. The presenter instances also contain methods that can create model objects from the validated user input. The result is a clean domain model and an easily unit testable presentation layer.

Above are, in my opinion, the significant changes we made to mold Rails to our needs on this project. There were a few other changes we made that were not as major but also contributed to the success we've had so far. For example, we stopped using migrations because of some pain we were feeling due to our team size. Instead, we drop and recreate our database with every build using ActiveRecord::Schema.define, a tip we picked up from Dave Thomas. We also automated our check in process to ensure everyone follows the same steps before checking in. This has lead us to very few broken builds.

Rails is great for building web applications. For building enterprise web applications, Rails is often good enough. And, for building complicated enterprise web applications, Rails is easily extendable. Because of this, Rails is Enterprise Ready.
Post a Comment