TimePilot for Rails.

Enabling new features for specific (groups of) users.


If you develop a software product in Ruby on Rails for many different users, you may very well find yourself wanting to enable certain new features for a specific group of users as a temporary pilot. Eventually the feature will become mainstream, but you first want to check out initial responses and possibly adapt to that.

Ever wrote code like this?

if customer.id == 232
# do awesome new stuff here
else
# do boring old stuff
end

And then, later, you’ll find yourself writing something like this:

if customer.id == 232 || [32,511,42,...].include?(user.team.id) || user.id == 23
# do awesome new stuff here
else
# do boring old stuff
end

Not very pretty. Not very maintainable. And for which users did you enable which feature again? Not to mention you have to redeploy your application every time you want enable awesome new stuff for another customer.

We had this very issue ourselves too often. That’s why we — @mlangenberg and I — wrote a little Gem that allows you to configure different pilots, which can then be enabled for different (groups of) users. All you really wanted to do in the code block above was:

if user.awesome_new_stuff_enabled?

With minimal configuration efforts:

# config/initializers/time_pilot.rb
TimePilot.configure do |c|
c.feature :awesome_new_stuff
end
# model/user.rb
class User
include TimePilot::Features
is_pilot_group
end

Now, for every user object, we can `enable_awesome_new_stuff’, `disable_awesome_new_stuff’ and check if the feature is enabled for a user with `awesome_new_stuff_enabled?’.

Enabling a feature can be simply done using the rails console:

User.find(42).enable_awesome_new_stuff

Hierarchy.

You can also define model hierarchy. A User may belong to an Organization. If you want to enable a feature for an entire organization, TimePilot allows you to specify it as such:

# model/user.rb
class User
belongs_to :organization
include TimePilot::Features
is_pilot_group overriden_by: [:organization]
end

# model/organisation.rb
class Organization
has_many :users
include TimePilot::Features
is_pilot_group
end

Now, when a feature has been enabled for an entire organization, invoking `awesome_new_stuff_enabled?’ on any user that belongs to that organization will yield true. The only prerequisite here is that you use ActiveModel relations so that `organization_id’ can be invoked on a user object.

It’s clean, simple and fast, as TimePilot uses Redis for storage. The only time you’ll have to redeploy for a feature now is when you introduce a new one, or want to remove a feature as pilot to fully enable it for all your users.


Get it.

Check out the project on github.com/nedap/time_pilot. TimePilot is also available through RubyGems.

Email me when Mark publishes or recommends stories