flipper-active_record 1.3.3 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 45c10d391c587e3416261de98fd324e912f4406d1f436fc44acadf3720ab6bd0
4
- data.tar.gz: d150526b605738b91bc37a0c7dab8964ad4b2ddcfa07bc5400739074e39af73b
3
+ metadata.gz: 6db1458b33ebce656ac2fd6a0aadeb5e2547b5cd346644ec64cf54034f93a461
4
+ data.tar.gz: ab9c8dee420bef036736f998a99411a89c70cdc794cdb96ec0af355a5a682902
5
5
  SHA512:
6
- metadata.gz: 72806c21616f5fe5abc4696898b8e0071ab23930c5789c88e235f71f5aa578e8814b19d1a292c8a58863a6666a2b50e00e79034b1277708896ae2f9f44099b99
7
- data.tar.gz: b6f5e80ea899277afcb0cde6b1ffeaed61171a2dc82ade9cc732dfb51f6f055bda327e8f9bacb5bbfb7f1e03fc33ad89e99c1c9fe863a21a5385049cc3cd00c0
6
+ metadata.gz: 4f8a73e94ebfdb0b1547ec276880c3c57e1b79320036af3f75c34bf6e8a1743b3a245351f5eaed5f4f4ed643a9bec6c8cec8954d1e2ac91ae71660b00c5a079d
7
+ data.tar.gz: a39fbf5b9517806fbaf22e303663ddd33e0a974d7e9913f5793c4ac3ef74cf9aa23782d4dacdad256b672c3a4dcc65b12aabb8520c30490147bf10449039631b
@@ -28,3 +28,18 @@ SQL
28
28
  ActiveRecord::Base.connection.execute <<-SQL
29
29
  CREATE UNIQUE INDEX index_gates_on_keys_and_value on flipper_gates (feature_key, key, value)
30
30
  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
@@ -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!"
@@ -8,40 +8,37 @@ module Flipper
8
8
  class ActiveRecord
9
9
  include ::Flipper::Adapter
10
10
 
11
- ActiveSupport.on_load(:active_record) do
12
- # Abstract base class for internal models
13
- class Model < ::ActiveRecord::Base
14
- self.abstract_class = true
15
- end
11
+ class Model < ::ActiveRecord::Base
12
+ self.abstract_class = true
13
+ end
16
14
 
17
- # Private: Do not use outside of this adapter.
18
- class Feature < Model
19
- self.table_name = [
20
- Model.table_name_prefix,
21
- "flipper_features",
22
- Model.table_name_suffix,
23
- ].join
15
+ # Private: Do not use outside of this adapter.
16
+ class Feature < Model
17
+ self.table_name = [
18
+ Model.table_name_prefix,
19
+ "flipper_features",
20
+ Model.table_name_suffix,
21
+ ].join
24
22
 
25
- has_many :gates, foreign_key: "feature_key", primary_key: "key"
23
+ has_many :gates, foreign_key: "feature_key", primary_key: "key"
26
24
 
27
- validates :key, presence: true
28
- end
25
+ validates :key, presence: true
26
+ end
29
27
 
30
- # Private: Do not use outside of this adapter.
31
- class Gate < Model
32
- self.table_name = [
33
- Model.table_name_prefix,
34
- "flipper_gates",
35
- Model.table_name_suffix,
36
- ].join
28
+ # Private: Do not use outside of this adapter.
29
+ class Gate < Model
30
+ self.table_name = [
31
+ Model.table_name_prefix,
32
+ "flipper_gates",
33
+ Model.table_name_suffix,
34
+ ].join
37
35
 
38
- validates :feature_key, presence: true
39
- validates :key, presence: true
40
- end
36
+ validates :feature_key, presence: true
37
+ validates :key, presence: true
41
38
  end
42
39
 
43
40
  VALUE_TO_TEXT_WARNING = <<-EOS
44
- Your database needs migrated to use the latest Flipper features.
41
+ Your database needs to be migrated to use the latest Flipper features.
45
42
  Run `rails generate flipper:update` and `rails db:migrate`.
46
43
  EOS
47
44
 
@@ -59,10 +56,8 @@ module Flipper
59
56
  # can roll your own tables and what not, if you so desire.
60
57
  def initialize(options = {})
61
58
  @name = options.fetch(:name, :active_record)
62
- @feature_class = options.fetch(:feature_class) { Feature }
63
- @gate_class = options.fetch(:gate_class) { Gate }
64
-
65
- warn VALUE_TO_TEXT_WARNING if value_not_text?
59
+ @feature_class = options.fetch(:feature_class) { Flipper::Adapters::ActiveRecord::Feature }
60
+ @gate_class = options.fetch(:gate_class) { Flipper::Adapters::ActiveRecord::Gate }
66
61
  end
67
62
 
68
63
  # Public: The set of known features.
@@ -289,15 +284,23 @@ module Flipper
289
284
  # Check if value column is text instead of string
290
285
  # See https://github.com/flippercloud/flipper/pull/692
291
286
  def value_not_text?
292
- @gate_class.column_for_attribute(:value).type != :text
287
+ with_connection(@gate_class) do |connection|
288
+ @gate_class.column_for_attribute(:value).type != :text
289
+ end
293
290
  rescue ::ActiveRecord::ActiveRecordError => error
294
291
  # If the table doesn't exist, the column doesn't exist either
295
292
  warn "#{error.message}. You likely need to run `rails g flipper:active_record` and/or `rails db:migrate`."
296
293
  end
297
294
 
298
295
  def with_connection(model = @feature_class, &block)
296
+ warn VALUE_TO_TEXT_WARNING if !warned_about_value_not_text? && value_not_text?
299
297
  model.connection_pool.with_connection(&block)
300
298
  end
299
+
300
+ def warned_about_value_not_text?
301
+ return @warned_about_value_not_text if defined?(@warned_about_value_not_text)
302
+ @warned_about_value_not_text = true
303
+ end
301
304
  end
302
305
  end
303
306
  end
@@ -1,5 +1,5 @@
1
1
  module Flipper
2
- VERSION = '1.3.3'.freeze
2
+ VERSION = '1.3.5'.freeze
3
3
 
4
4
  REQUIRED_RUBY_VERSION = '2.6'.freeze
5
5
  NEXT_REQUIRED_RUBY_VERSION = '3.0'.freeze
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 1.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-02-24 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: flipper
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 1.3.3
18
+ version: 1.3.5
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 1.3.3
25
+ version: 1.3.5
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: activerecord
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -54,6 +54,7 @@ files:
54
54
  - examples/active_record/ar_setup.rb
55
55
  - examples/active_record/basic.rb
56
56
  - examples/active_record/cached.rb
57
+ - examples/active_record/group_migration.rb
57
58
  - examples/active_record/internals.rb
58
59
  - flipper-active_record.gemspec
59
60
  - lib/flipper-active_record.rb
@@ -72,7 +73,7 @@ metadata:
72
73
  homepage_uri: https://www.flippercloud.io
73
74
  source_code_uri: https://github.com/flippercloud/flipper
74
75
  bug_tracker_uri: https://github.com/flippercloud/flipper/issues
75
- changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.3.3
76
+ changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.3.5
76
77
  funding_uri: https://github.com/sponsors/flippercloud
77
78
  rdoc_options: []
78
79
  require_paths:
@@ -88,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
89
  - !ruby/object:Gem::Version
89
90
  version: '0'
90
91
  requirements: []
91
- rubygems_version: 3.6.5
92
+ rubygems_version: 3.6.9
92
93
  specification_version: 4
93
94
  summary: ActiveRecord feature flag adapter for Flipper
94
95
  test_files: