Skip to content

Commit fc88d91

Browse files
committed
Add example for group migration
1 parent e6fbdb2 commit fc88d91

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

examples/active_record/ar_setup.rb

+15
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,18 @@
2828
ActiveRecord::Base.connection.execute <<-SQL
2929
CREATE UNIQUE INDEX index_gates_on_keys_and_value on flipper_gates (feature_key, key, value)
3030
SQL
31+
32+
ActiveRecord::Base.connection.execute <<-SQL
33+
CREATE TABLE users (
34+
id integer PRIMARY KEY,
35+
name string NOT NULL,
36+
influencer boolean,
37+
created_at datetime NOT NULL,
38+
updated_at datetime NOT NULL
39+
)
40+
SQL
41+
42+
require 'flipper/model/active_record'
43+
class User < ActiveRecord::Base
44+
include Flipper::Model::ActiveRecord
45+
end
+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# This is an example script that shows how to migrate from a bunch of individual
2+
# actors to a group. Should be useful for those who have ended up with large
3+
# actor sets and want to slim them down for performance reasons.
4+
5+
require_relative "./ar_setup"
6+
require 'flipper/adapters/active_record'
7+
require 'active_support/all'
8+
9+
# 1. enable feature for 100 actors, make 80 influencers
10+
users = 100.times.map do |n|
11+
influencer = n < 80 ? true : false
12+
user = User.create(name: n, influencer: influencer)
13+
Flipper.enable :stats, user
14+
user
15+
end
16+
17+
# check enabled, should all be because individual actors are enabled
18+
print 'Should be [[true, 100]]: '
19+
print users.group_by { |user| Flipper.enabled?(:stats, user) }.map { |result, users| [result, users.size]}
20+
puts
21+
22+
# 2. register a group so flipper knows what to do with it
23+
Flipper.register(:influencers) do |actor, context|
24+
actor.respond_to?(:influencer) && actor.influencer
25+
end
26+
27+
# 3. enable group for feature, THIS IS IMPORTANT
28+
Flipper.enable :stats, :influencers
29+
30+
# check enabled again, should all still be true because individual actors are
31+
# enabled, but also the group gate would return true for 80 influencers. At this
32+
# point, it's kind of double true but flipper just cares if any gate returns true.
33+
print 'Should be [[true, 100]]: '
34+
print users.group_by { |user| Flipper.enabled?(:stats, user) }.map { |result, users| [result, users.size]}
35+
puts
36+
37+
# 4. now we want to clean up the actors that are covered by the group to slim down
38+
# the actor set size. So we loop through actors and remove them if group returns
39+
# true for the provided actor and context.
40+
Flipper[:stats].actors_value.each do |flipper_id|
41+
# Hydrate the flipper_id into an active record object. Modify this based on
42+
# your flipper_id's if you use anything other than active record models and
43+
# the default flipper_id provided by flipper.
44+
class_name, id = flipper_id.split(';')
45+
klass = class_name.constantize
46+
user = klass.find(id)
47+
48+
# if user is in group then disable for actor because they'll still get the feature
49+
context = Flipper::FeatureCheckContext.new(
50+
feature_name: :stats,
51+
values: Flipper[:stats].gate_values,
52+
actors: [Flipper::Types::Actor.wrap(user)]
53+
)
54+
55+
if Flipper::Gates::Group.new.open?(context)
56+
Flipper.disable(:stats, user)
57+
end
58+
end
59+
60+
# check enabled again, should be the same result as previous checks
61+
print 'Should be [[true, 100]]: '
62+
print users.group_by { |user| Flipper.enabled?(:stats, user) }.map { |result, users| [result, users.size]}
63+
puts
64+
65+
puts "Actors enabled: #{Flipper[:stats].actors_value.size}"
66+
puts "Groups enabled: #{Flipper[:stats].groups_value.size}"
67+
68+
puts "All actors that could be migrated to groups were migrated. Yay!"

0 commit comments

Comments
 (0)