Feature Flippers with Rails

flipper!A few months ago, I read a blog post by the Flickr developers on how they built an internal tool called a "feature flipper". A feature flipper lets a site admin deploy/rollback features from a simple dashboard with a single click. Think of being able to add an on/off switch to any piece of code in your application. This has two main benefits: 1) no more merging branches 2) more control of user experience. While some people may enjoy merging branches (and going to the dentist), I'd rather avoid it. A good feature flipping system can also help you be more agile: if your application takes X minutes to deploy, you save X minutes each time you deploy or rollback a new feature. Control of features moves from Git (or Mercurial or whatever) to the application itself. (This also has some disadvantages--they're listed in the Flickr post). The Flickr post described how they used PHP to build a feature flipper. In this post, I'm going to show you how to implement a basic feature flipper for Ruby on Rails. I'll show you the finished product first. Use it in a view: Or in a controller: Then from a simple dashboard, turn the features on or off: The first step is to create a model called Feature which has the following columns: id:int, name:varchar, deployed:boolean, and timestamps. Use a migration, write sql in your db admin program, whatever. Next, create a controller called features_controller.rb with the following code: Create a view in the app/views/features folder called index.html.erb (or .haml etc): This view iterates through all Feature instances, and creates a form for each one. If the feature is deployed, the form contains a hidden value to rollback. If the feature is rolled back, the form contains a hidden value to deploy. Pay close attention to lines 13, 14, and 17. Now how do we create new features? Instead of using a form to add new features, I wrote a helper method that lets developers add features by simply writing code. In app/helpers/application_helper.rb: If the feature is already in the database, check if it's deployed. Otherwise, add the new feature to the database and have it set to false by default (line 8). This style of code was inspired by A/Bingo, an open-source A/B testing suite for Rails apps. Check it out! This feature flipping system is really lightweight, simple, and easy to use. At a minimum, I hope this post gets you to a good starting point. You can add more layers of functionality such as awareness of environment (production or development). Quick update: a couple of people have mentioned the performance hit from putting all these db queries throughout the code. One way around this is to use a cache. Set the reset for a really long time. Then add a method to reset the cache anytime a feature is flipped. The Flickr guys figured out a way around this, as did bootstrap startup hero, Patrick McKenzie with A/Bingo.
Alan 19 May 2010