flipper-active_record 0.21.0 → 0.25.0

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: 817d24520675d09850b573dd90cc0d3156d9814660df8f9e5e3ae0454c7ba2be
4
- data.tar.gz: 0f463aae2f5b685c468adece153f1d90a9da712f105dd473d54a09cdf212a2e5
3
+ metadata.gz: 4432d45cbc87e12df5a8de40225e97a2d7c9b04f67f9e7ee640b9bd13ec24ba7
4
+ data.tar.gz: 8027fea6e1bc7cc2bddfcbd72f1ec7624354186739ff57856b5c534f6f94bc65
5
5
  SHA512:
6
- metadata.gz: 57808e710308f1644695be92077fd70dedac3b0c513888fcdcef8afcbe7f5a271bab928c352fdc1e1d4c91ce42df2dd2ac71a7ecff352403a33d7231072f783d
7
- data.tar.gz: 20cc9301fd6e53258e14737bc0fd9b97e2e5c78a9bb6eea147b2cc0c539ee44dbf46388730d2114972577f2e3e5adc5b9dd0433bcfe25edcc9cfcb01ff8af0a4
6
+ metadata.gz: 738c9be60a2aa4f9e66f20bbe5d18e02ea9c57491136cd9f567fa48baa4ced3e6d44ab45e9d7ff4a3eead067d147556e1afc0c40205158910e2162843dd21921
7
+ data.tar.gz: c37ce69fbf80ec2fe653c53d9128ea02dc660524e419ac0fd91a2fdf7b4835f1f1c2652803b49d12dbad11ec9a60a1f0dfc96684e52ef16916adf2b5d235fbed
@@ -25,5 +25,5 @@ Gem::Specification.new do |gem|
25
25
  gem.metadata = Flipper::METADATA
26
26
 
27
27
  gem.add_dependency 'flipper', "~> #{Flipper::VERSION}"
28
- gem.add_dependency 'activerecord', '>= 5.0', '< 7'
28
+ gem.add_dependency 'activerecord', '>= 4.2', '< 8'
29
29
  end
@@ -7,21 +7,26 @@ module Flipper
7
7
  class ActiveRecord
8
8
  include ::Flipper::Adapter
9
9
 
10
+ # Abstract base class for internal models
11
+ class Model < ::ActiveRecord::Base
12
+ self.abstract_class = true
13
+ end
14
+
10
15
  # Private: Do not use outside of this adapter.
11
- class Feature < ::ActiveRecord::Base
16
+ class Feature < Model
12
17
  self.table_name = [
13
- ::ActiveRecord::Base.table_name_prefix,
18
+ Model.table_name_prefix,
14
19
  "flipper_features",
15
- ::ActiveRecord::Base.table_name_suffix,
20
+ Model.table_name_suffix,
16
21
  ].join
17
22
  end
18
23
 
19
24
  # Private: Do not use outside of this adapter.
20
- class Gate < ::ActiveRecord::Base
25
+ class Gate < Model
21
26
  self.table_name = [
22
- ::ActiveRecord::Base.table_name_prefix,
27
+ Model.table_name_prefix,
23
28
  "flipper_gates",
24
- ::ActiveRecord::Base.table_name_suffix,
29
+ Model.table_name_suffix,
25
30
  ].join
26
31
  end
27
32
 
@@ -101,11 +106,12 @@ module Flipper
101
106
  end
102
107
 
103
108
  def get_all
104
- rows = ::ActiveRecord::Base.connection.select_all <<-SQL.tr("\n", ' ')
105
- SELECT ff.key AS feature_key, fg.key, fg.value
106
- FROM #{@feature_class.table_name} ff
107
- LEFT JOIN #{@gate_class.table_name} fg ON ff.key = fg.feature_key
108
- SQL
109
+ features = ::Arel::Table.new(@feature_class.table_name.to_sym)
110
+ gates = ::Arel::Table.new(@gate_class.table_name.to_sym)
111
+ rows_query = features.join(gates, Arel::Nodes::OuterJoin)
112
+ .on(features[:key].eq(gates[:feature_key]))
113
+ .project(features[:key].as('feature_key'), gates[:key], gates[:value])
114
+ rows = @feature_class.connection.select_all rows_query
109
115
  db_gates = rows.map { |row| Gate.new(row) }
110
116
  grouped_db_gates = db_gates.group_by(&:feature_key)
111
117
  result = Hash.new { |hash, key| hash[key] = default_config }
@@ -172,10 +178,15 @@ module Flipper
172
178
  @gate_class.transaction do
173
179
  clear(feature) if clear_feature
174
180
  @gate_class.where(feature_key: feature.key, key: gate.key).destroy_all
175
- @gate_class.create! do |g|
176
- g.feature_key = feature.key
177
- g.key = gate.key
178
- g.value = thing.value.to_s
181
+ begin
182
+ @gate_class.create! do |g|
183
+ g.feature_key = feature.key
184
+ g.key = gate.key
185
+ g.value = thing.value.to_s
186
+ end
187
+ rescue ::ActiveRecord::RecordNotUnique
188
+ # assume this happened concurrently with the same thing and its fine
189
+ # see https://github.com/jnunemaker/flipper/issues/544
179
190
  end
180
191
  end
181
192
 
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.21.0'.freeze
2
+ VERSION = '0.25.0'.freeze
3
3
  end
@@ -1,6 +1,4 @@
1
- require 'helper'
2
1
  require 'flipper/adapters/active_record'
3
- require 'flipper/spec/shared_adapter_specs'
4
2
 
5
3
  # Turn off migration logging for specs
6
4
  ActiveRecord::Migration.verbose = false
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.0
4
+ version: 0.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-09 00:00:00.000000000 Z
11
+ date: 2022-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: flipper
@@ -16,34 +16,34 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.21.0
19
+ version: 0.25.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.21.0
26
+ version: 0.25.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '5.0'
33
+ version: '4.2'
34
34
  - - "<"
35
35
  - !ruby/object:Gem::Version
36
- version: '7'
36
+ version: '8'
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- version: '5.0'
43
+ version: '4.2'
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
- version: '7'
46
+ version: '8'
47
47
  description:
48
48
  email:
49
49
  - nunemaker@gmail.com
@@ -51,7 +51,6 @@ executables: []
51
51
  extensions: []
52
52
  extra_rdoc_files: []
53
53
  files:
54
- - docs/active_record/README.md
55
54
  - examples/active_record/ar_setup.rb
56
55
  - examples/active_record/basic.rb
57
56
  - examples/active_record/internals.rb
@@ -84,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
83
  - !ruby/object:Gem::Version
85
84
  version: '0'
86
85
  requirements: []
87
- rubygems_version: 3.0.3
86
+ rubygems_version: 3.1.2
88
87
  signing_key:
89
88
  specification_version: 4
90
89
  summary: ActiveRecord adapter for Flipper
@@ -1,156 +0,0 @@
1
- # Flipper ActiveRecord
2
-
3
- An ActiveRecord adapter for [Flipper](https://github.com/jnunemaker/flipper).
4
-
5
- Supported Active Record versions:
6
-
7
- * 5.0.x
8
- * 6.0.x
9
-
10
- ## Installation
11
-
12
- Add this line to your application's Gemfile:
13
-
14
- gem 'flipper-active_record'
15
-
16
- And then execute:
17
-
18
- $ bundle
19
-
20
- Or install it yourself with:
21
-
22
- $ gem install flipper-active_record
23
-
24
- ## Usage
25
-
26
- For your convenience a migration generator is provided to create the necessary migrations for using the active record adapter. By default this generates a migration that will create two database tables - `flipper_features` and `flipper_gates`.
27
-
28
- $ rails g flipper:active_record
29
-
30
- Note that the active record adapter requires the database tables to be created in order to work; failure to run the migration first will cause an exception to be raised when attempting to initialize the active record adapter.
31
-
32
- Flipper will be configured to use the ActiveRecord adapter when `flipper-active_record` is loaded. But **if you need to customize the adapter**, you can add this to an initializer:
33
-
34
- ```ruby
35
- require 'flipper/adapters/active_record'
36
- Flipper.configure do |config|
37
- config.adapter { Flipper::Adapters::ActiveRecord.new }
38
- end
39
- ```
40
-
41
- ## Internals
42
-
43
- Each feature is stored as a row in a features table. Each gate is stored as a row in a gates table, related to the feature by the feature's key.
44
-
45
- ```ruby
46
- # Register a few groups.
47
- Flipper.register(:admins) { |thing| thing.admin? }
48
- Flipper.register(:early_access) { |thing| thing.early_access? }
49
-
50
- # Create a user class that has flipper_id instance method.
51
- User = Struct.new(:flipper_id)
52
-
53
- Flipper.enable :stats
54
- Flipper.enable_group :stats, :admins
55
- Flipper.enable_group :stats, :early_access
56
- Flipper.enable_actor :stats, User.new('25')
57
- Flipper.enable_actor :stats, User.new('90')
58
- Flipper.enable_actor :stats, User.new('180')
59
- Flipper.enable_percentage_of_time :stats, 15
60
- Flipper.enable_percentage_of_actors :stats, 45
61
-
62
- Flipper.enable :search
63
-
64
- puts 'all rows in features table'
65
- pp Flipper::Adapters::ActiveRecord::Feature.all
66
- # [#<Flipper::Adapters::ActiveRecord::Feature:0x007fd259b47110
67
- # id: 1,
68
- # key: "stats",
69
- # created_at: 2015-12-21 16:26:29 UTC,
70
- # updated_at: 2015-12-21 16:26:29 UTC>,
71
- # #<Flipper::Adapters::ActiveRecord::Feature:0x007fd259b46cd8
72
- # id: 2,
73
- # key: "search",
74
- # created_at: 2015-12-21 16:26:29 UTC,
75
- # updated_at: 2015-12-21 16:26:29 UTC>]
76
- puts
77
-
78
- puts 'all rows in gates table'
79
- pp Flipper::Adapters::ActiveRecord::Gate.all
80
- # [#<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0f0f8
81
- # id: 1,
82
- # feature_key: "stats",
83
- # key: "boolean",
84
- # value: "true",
85
- # created_at: 2015-12-21 16:26:29 UTC,
86
- # updated_at: 2015-12-21 16:26:29 UTC>,
87
- # #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0ebd0
88
- # id: 2,
89
- # feature_key: "stats",
90
- # key: "groups",
91
- # value: "admins",
92
- # created_at: 2015-12-21 16:26:29 UTC,
93
- # updated_at: 2015-12-21 16:26:29 UTC>,
94
- # #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0e748
95
- # id: 3,
96
- # feature_key: "stats",
97
- # key: "groups",
98
- # value: "early_access",
99
- # created_at: 2015-12-21 16:26:29 UTC,
100
- # updated_at: 2015-12-21 16:26:29 UTC>,
101
- # #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0e568
102
- # id: 4,
103
- # feature_key: "stats",
104
- # key: "actors",
105
- # value: "25",
106
- # created_at: 2015-12-21 16:26:29 UTC,
107
- # updated_at: 2015-12-21 16:26:29 UTC>,
108
- # #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0e0b8
109
- # id: 5,
110
- # feature_key: "stats",
111
- # key: "actors",
112
- # value: "90",
113
- # created_at: 2015-12-21 16:26:29 UTC,
114
- # updated_at: 2015-12-21 16:26:29 UTC>,
115
- # #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0da50
116
- # id: 6,
117
- # feature_key: "stats",
118
- # key: "actors",
119
- # value: "180",
120
- # created_at: 2015-12-21 16:26:29 UTC,
121
- # updated_at: 2015-12-21 16:26:29 UTC>,
122
- # #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0d3c0
123
- # id: 7,
124
- # feature_key: "stats",
125
- # key: "percentage_of_time",
126
- # value: "15",
127
- # created_at: 2015-12-21 16:26:29 UTC,
128
- # updated_at: 2015-12-21 16:26:29 UTC>,
129
- # #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0cdf8
130
- # id: 8,
131
- # feature_key: "stats",
132
- # key: "percentage_of_actors",
133
- # value: "45",
134
- # created_at: 2015-12-21 16:26:29 UTC,
135
- # updated_at: 2015-12-21 16:26:29 UTC>,
136
- # #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0cbf0
137
- # id: 9,
138
- # feature_key: "search",
139
- # key: "boolean",
140
- # value: "true",
141
- # created_at: 2015-12-21 16:26:29 UTC,
142
- # updated_at: 2015-12-21 16:26:29 UTC>]
143
- puts
144
-
145
- puts 'flipper get of feature'
146
- pp adapter.get(flipper[:stats])
147
- # flipper get of feature
148
- ```
149
-
150
- ## Contributing
151
-
152
- 1. Fork it
153
- 2. Create your feature branch (`git checkout -b my-new-feature`)
154
- 3. Commit your changes (`git commit -am 'Added some feature'`)
155
- 4. Push to the branch (`git push origin my-new-feature`)
156
- 5. Create new Pull Request