Feature is a battle-tested feature toggle library for ruby.
The feature toggle functionality has to be configured by feature repositories. A feature repository simply provides lists of active features (symbols!). Unknown features are assumed inactive.
With this approach Feature is highly configurable and not bound to a specific kind of configuration.
NOTE: The current gem version works with Ruby 2+ and supports Ruby on Rails 4+.
NOTE: Ruby 1.9 is supported until version 1.2.0, Ruby 1.8 is supported until version 0.7.0.
NOTE: ActiveRecord / Rails 3 is supported until version 1.1.0.
gem install feature
-
Setup Feature
-
Create a repository (for more infos about configuration backends, see section below)
require 'feature' repo = Feature::Repository::SimpleRepository.new
-
Set repository to Feature
Feature.set_repository(repo)
-
-
Use Feature in your production code
Feature.active?(:feature_name) # => true/false Feature.inactive?(:feature_name) # => true/false Feature.active_features # => [:list, :of, :features] Feature.with(:feature_name) do # code end Feature.without(:feature_name) do # code end # this returns value_true if :feature_name is active, otherwise value_false Feature.switch(:feature_name, value_true, value_false) # switch may also take Procs that will be evaluated and it's result returned. Feature.switch(:feature_name, -> { code... }, -> { code... })
-
Use Feature in your test code (for reliable testing of feature depending code)
require 'feature/testing' Feature.run_with_activated(:feature) do # your test code end # you also can give a list of features Feature.run_with_deactivated(:feature, :another_feature) do # your test code end
-
Feature-toggle caching
-
By default, Feature will lazy-load the active features from the underlying repository the first time you try to check whether a feature is set or not.
-
Subsequent calls to Feature will access the cached in-memory representation of the list of features. So changes to toggles in the underlying repository would not be reflected in the application until you restart the application or manually call
Feature.refresh!
-
You can optionally pass in true as a second argument on set_repository, to force Feature to auto-refresh the feature list on every feature-toggle check you make.
Feature.set_repository(your_repository, true)
-
You can also optionally pass in a number as second argument on set_repository, to force Feature to refresh the feature list after X seconds. This will be done only on demand by a request.
Feature.set_repository(your_repository, 60)
-
# File: Gemfile
gem 'feature'
# setup code
require 'feature'
repo = Feature::Repository::SimpleRepository.new
repo.add_active_feature :be_nice
Feature.set_repository repo
# See here to learn how to configure redis: https://github.com/redis/redis-rb
# File: Gemfile
gem 'feature'
gem 'redis'
# setup code (or Rails initializer: config/initializers/feature.rb)
require 'feature'
# "feature_toggles" will be the key name in redis
repo = Feature::Repository::RedisRepository.new("feature_toggles")
Feature.set_repository repo
# add/toggle features in Redis
Redis.current.hset("feature_toggles", "ActiveFeature", true)
Redis.current.hset("feature_toggles", "InActiveFeature", false)
# File: Gemfile
gem 'feature'
# File: config/feature.yml
features:
an_active_feature: true
an_inactive_feature: false
# setup code (or Rails initializer: config/initializers/feature.rb)
repo = Feature::Repository::YamlRepository.new("#{Rails.root}/config/feature.yml")
Feature.set_repository repo
You may also specify a Rails environment to use a new feature in development and test, but not production:
# File: config/feature.yml
test:
features:
a_new_feature: true
production:
features:
a_new_feature: false
# File: config/initializers/feature.rb
repo = Feature::Repository::YamlRepository.new("#{Rails.root}/config/feature.yml", Rails.env)
Feature.set_repository repo
# File: Gemfile
gem 'feature'
# Run generator and migrations
$ rails g feature:install
$ rake db:migrate
# Add Features to table FeaturesToggle for example in
# File: db/schema.rb
FeatureToggle.create!(name: "ActiveFeature", active: true)
FeatureToggle.create!(name: "InActiveFeature", active: false)
# or in initializer
# File: config/initializers/feature.rb
repo.add_active_feature(:active_feature)