Skip to content

Getting started with Featury

Conventions

  • All feature classes are subclasses of Featury::Base and are located in the app/features directory. Common practice: create ApplicationFeature::Base as the base class for your features.
  • Use namespaces that match model names, and name the class as a noun describing the process. Use noun forms: RegistrationFeature, not RegisterFeature. Example: User::RegistrationFeature, Order::FulfillmentFeature.

Version support

Ruby/Rails8.18.07.27.17.06.16.05.25.15.0
4.0
3.4
3.3
3.2
3.1

Installation

Add this to Gemfile:

ruby
gem "featury"

And execute:

shell
bundle install

Preparation

As a first step, it is recommended to prepare the base class for further inheritance. This base class should contain actions within itself with the integration of the tool for features in the project. For example, it could be an ActiveRecord model, Flipper, or something else.

ActiveRecord model

The FeatureFlag model will be used as an example.

ruby
module ApplicationFeature
  class Base < Featury::Base
    action :enabled? do |features:, **options|
      features.all? do |feature|
        FeatureFlag
          .find_or_create_by!(code: feature, actor: options[:user])
          .enabled?
      end
    end

    action :disabled? do |features:, **options|
      features.any? do |feature|
        !FeatureFlag
          .find_or_create_by!(code: feature, actor: options[:user])
          .enabled?
      end
    end

    action :enable do |features:, **options|
      features.all? do |feature|
        FeatureFlag
          .find_or_create_by!(code: feature, actor: options[:user])
          .update!(enabled: true)
      end
    end

    action :disable do |features:, **options|
      features.all? do |feature|
        FeatureFlag
          .find_or_create_by!(code: feature, actor: options[:user])
          .update!(enabled: false)
      end
    end

    before do |action:, features:|
      Slack::API::Notify.call!(action:, features:)
    end

    after :enabled?, :disabled? do |action:, features:|
      Slack::API::Notify.call!(action:, features:)
    end
  end
end