We are exploring using the flipper gem (https://github.com/jnunemaker/flipper) to gate who sees new features. In one of our first tests, we want to show a specific feature to only the first X users that see a banner promoting it.
We looked at using a percentage, but the business is very specific on the number, and also wants to reach that number right away, then disable the feature for all other users, without disabling it for those that saw it first. Using a percentage, we weren't able to see a way to ensure the correct number would see it, and that everyone of the first x would see it.
Inside the gates/actor.rb, there is this:
enabled_actor_ids = value
You should be able to accomplish this by programmatically turning the feature on for Individual Actors until an upper limit is reached.
IMPORTANT NOTE: according to the documentation:
The individual actor gate is typically not designed for hundreds or thousands of actors to be enabled. This is an explicit choice to make it easier to batch load data from the adapters instead of performing individual checks for actors over and over. If you need to enable something for more than 20 individual people, I would recommend using a group.
Now that we've agreed that we want to move forward with this anyways.. Let's talk about implementation.
The first thing you need to do is to ensure that the actor (probably a User) responds to
flipper_id and that the
flipper_id is unique for every actor. Once that is set up, you should be able to simply do enable the feature for a user when they see the banner like this:
Now, in order to determine if we should enable the feature for a user, we need to determine how many users have been enrolled in the feature.
To do this we can query the Gate directly:
Flipper::Adapters::ActiveRecord::Gate.where( feature_key: "stats", key: "actors" ).count
This will return a count of the number of actors enrolled in a feature.
Well, let's take a look at the gem.
flipper[:stats].enable_actor actually calls
Feature#enable_actor with the
user we passed in earlier (that responds to
flipper_id) being passed in as the actor.
Feature#enable_actor passes the actor into
Types::Actor.wrap which creates a new instance of Types::Actor which checks to make sure the actor isn't nil and that it has a flipper_id and then sets two instance variables,
thing which is set to the actor, and
value which is set to the
flipper_id of the actor.
Now that we have an instance of
Types::Actor, we pass it into
Feature#enable which looks up the
gate which in our case would be a
Gates::Actor instance. Finally we call enable on the adaptor (which in your case is ActiveRecord).
Adapters::ActiveRecord.enable we first look at
gate.data_type which in our case, is
:set. From there we do:
@gate_class.create! do |g| g.feature_key = feature.key g.key = gate.key g.value = thing.value.to_s end
Where, as mentioned earlier,
thing.value is the
@gate_class is the active record class responsible for the gates table and the default table name is "flipper_gates".
Now we know exactly what to query to get a count of the actors enrolled in the feature!
number_of_actors_enrolled_in_stats_feature = Flipper::Adapters::ActiveRecord::Gate.where( feature_key: "stats", key: "actors" ).count