| Our site (http://gre.magoosh.com) serves up content for a variety of exams, each of which is accessible from a single subdomain. Since content is developed for the exams somewhat independently, we have to be able to roll out releases at different speeds per exam, so we needed a solution a bit more complex than just feature flags -- here's the solution I built: We keep a table of feature releases, each with a reference to the exam, a slug to identify the feature and an number from 0 to 100 indicating their status in the release cycle (100 = disabled, 75 = alpha, 50 = private beta, 25 = public beta, 0 = full release, etc.). Then each user is also assigned an integer which indicates the point in the release cycle at which they get to see features (0 by default). When we want to give them access to a feature, we just adjust their release access accordingly. All this is controlled through the admin interface. We then use a helper (in views and server-side), feature_active_for?(feature_slug, user) which returns true the exam has the feature enabled and if the release status is less than or equal to the user's release access, so we can do stuff like: if feature_active_for?(:lesson_videos, current_user) # use video template else # use plain text template end This has worked really well so far, giving the non-technical content producers and customer support the ability to manage releases as they test content. However, the biggest advantage is that we can now give customers access to features before their public release to build goodwill after support requests and gather feedback. (we've been giving out a fraction of the refunds that we did before the release control) I haven't actually removed any of the feature flags yet (we can reuse the release process for each other exam that we develop content for) but I'll probably remove one when it if becomes an integral part of the product across all of our exams. It would actually be pretty easy to just add to the helper to intercept release status checks and ease up on database requests. This is probably all a bit more complicated than what you'll need, but I hope it helps. |