flipper-active_record 1.3.6 → 1.4.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 +4 -4
- data/lib/flipper/adapters/active_record/feature.rb +20 -0
- data/lib/flipper/adapters/active_record/gate.rb +19 -0
- data/lib/flipper/adapters/active_record/model.rb +9 -0
- data/lib/flipper/adapters/active_record.rb +34 -39
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/adapters/active_record_spec.rb +146 -33
- data/test/adapters/active_record_test.rb +16 -0
- metadata +14 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d550530c982b783d5bb01547b0dd63e65ae28cf684baf5cab91f633b45546a6a
|
|
4
|
+
data.tar.gz: abe3da9138ef86cc0a7fecf5496d4ac78b036cfb9f8188b782debf9be8ab92ba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fe247ffa161d7090ff3630a50329f128c75b7ef65109b9a9fb85bd4432892752d7f106b21bf05f9cf5de913ed43e72f18d9316e9775300d9cc7be4c571c8f492
|
|
7
|
+
data.tar.gz: 82583bfa629d02c3eeba04b9cb7b32ba78ff65fcb39bba598c07e9a9dc843a486fe3a08351b528db3a1d032a7632593af92a6b1045c0d2af568c30974474c684
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'flipper/adapters/active_record/model'
|
|
2
|
+
|
|
3
|
+
module Flipper
|
|
4
|
+
module Adapters
|
|
5
|
+
class ActiveRecord
|
|
6
|
+
# Private: Do not use outside of this adapter.
|
|
7
|
+
class Feature < Model
|
|
8
|
+
self.table_name = [
|
|
9
|
+
Model.table_name_prefix,
|
|
10
|
+
"flipper_features",
|
|
11
|
+
Model.table_name_suffix,
|
|
12
|
+
].join
|
|
13
|
+
|
|
14
|
+
has_many :gates, foreign_key: "feature_key", primary_key: "key"
|
|
15
|
+
|
|
16
|
+
validates :key, presence: true
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'flipper/adapters/active_record/model'
|
|
2
|
+
|
|
3
|
+
module Flipper
|
|
4
|
+
module Adapters
|
|
5
|
+
class ActiveRecord
|
|
6
|
+
# Private: Do not use outside of this adapter.
|
|
7
|
+
class Gate < Model
|
|
8
|
+
self.table_name = [
|
|
9
|
+
Model.table_name_prefix,
|
|
10
|
+
"flipper_gates",
|
|
11
|
+
Model.table_name_suffix,
|
|
12
|
+
].join
|
|
13
|
+
|
|
14
|
+
validates :feature_key, presence: true
|
|
15
|
+
validates :key, presence: true
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -2,43 +2,15 @@ require 'set'
|
|
|
2
2
|
require 'securerandom'
|
|
3
3
|
require 'flipper'
|
|
4
4
|
require 'active_record'
|
|
5
|
+
require_relative 'active_record/model'
|
|
6
|
+
require_relative 'active_record/feature'
|
|
7
|
+
require_relative 'active_record/gate'
|
|
5
8
|
|
|
6
9
|
module Flipper
|
|
7
10
|
module Adapters
|
|
8
11
|
class ActiveRecord
|
|
9
12
|
include ::Flipper::Adapter
|
|
10
13
|
|
|
11
|
-
ActiveSupport.on_load(:active_record) do
|
|
12
|
-
class Model < ::ActiveRecord::Base
|
|
13
|
-
self.abstract_class = true
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Private: Do not use outside of this adapter.
|
|
17
|
-
class Feature < Model
|
|
18
|
-
self.table_name = [
|
|
19
|
-
Model.table_name_prefix,
|
|
20
|
-
"flipper_features",
|
|
21
|
-
Model.table_name_suffix,
|
|
22
|
-
].join
|
|
23
|
-
|
|
24
|
-
has_many :gates, foreign_key: "feature_key", primary_key: "key"
|
|
25
|
-
|
|
26
|
-
validates :key, presence: true
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Private: Do not use outside of this adapter.
|
|
30
|
-
class Gate < Model
|
|
31
|
-
self.table_name = [
|
|
32
|
-
Model.table_name_prefix,
|
|
33
|
-
"flipper_gates",
|
|
34
|
-
Model.table_name_suffix,
|
|
35
|
-
].join
|
|
36
|
-
|
|
37
|
-
validates :feature_key, presence: true
|
|
38
|
-
validates :key, presence: true
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
14
|
VALUE_TO_TEXT_WARNING = <<-EOS
|
|
43
15
|
Your database needs to be migrated to use the latest Flipper features.
|
|
44
16
|
Run `rails generate flipper:update` and `rails db:migrate`.
|
|
@@ -69,7 +41,7 @@ module Flipper
|
|
|
69
41
|
|
|
70
42
|
# Public: Adds a feature to the set of known features.
|
|
71
43
|
def add(feature)
|
|
72
|
-
|
|
44
|
+
with_write_connection(@feature_class) do
|
|
73
45
|
@feature_class.transaction(requires_new: true) do
|
|
74
46
|
begin
|
|
75
47
|
# race condition, but add is only used by enable/disable which happen
|
|
@@ -88,7 +60,7 @@ module Flipper
|
|
|
88
60
|
|
|
89
61
|
# Public: Removes a feature from the set of known features.
|
|
90
62
|
def remove(feature)
|
|
91
|
-
|
|
63
|
+
with_write_connection(@feature_class) do
|
|
92
64
|
@feature_class.transaction do
|
|
93
65
|
@feature_class.where(key: feature.key).destroy_all
|
|
94
66
|
clear(feature)
|
|
@@ -99,7 +71,7 @@ module Flipper
|
|
|
99
71
|
|
|
100
72
|
# Public: Clears the gate values for a feature.
|
|
101
73
|
def clear(feature)
|
|
102
|
-
|
|
74
|
+
with_write_connection(@gate_class) { @gate_class.where(feature_key: feature.key).destroy_all }
|
|
103
75
|
true
|
|
104
76
|
end
|
|
105
77
|
|
|
@@ -128,7 +100,7 @@ module Flipper
|
|
|
128
100
|
end
|
|
129
101
|
end
|
|
130
102
|
|
|
131
|
-
def get_all
|
|
103
|
+
def get_all(**kwargs)
|
|
132
104
|
with_connection(@feature_class) do |connection|
|
|
133
105
|
# query the gates from the db in a single query
|
|
134
106
|
features = ::Arel::Table.new(@feature_class.table_name.to_sym)
|
|
@@ -151,6 +123,7 @@ module Flipper
|
|
|
151
123
|
features.each do |feature|
|
|
152
124
|
result[feature.key] = result_for_gates(feature, grouped_gates[feature.key])
|
|
153
125
|
end
|
|
126
|
+
result.default_proc = nil
|
|
154
127
|
result
|
|
155
128
|
end
|
|
156
129
|
end
|
|
@@ -193,9 +166,11 @@ module Flipper
|
|
|
193
166
|
when :integer
|
|
194
167
|
set(feature, gate, thing)
|
|
195
168
|
when :json
|
|
196
|
-
|
|
169
|
+
with_write_connection(@gate_class) do
|
|
170
|
+
delete(feature, gate)
|
|
171
|
+
end
|
|
197
172
|
when :set
|
|
198
|
-
|
|
173
|
+
with_write_connection(@gate_class) do
|
|
199
174
|
@gate_class.where(feature_key: feature.key, key: gate.key, value: thing.value).destroy_all
|
|
200
175
|
end
|
|
201
176
|
else
|
|
@@ -218,7 +193,7 @@ module Flipper
|
|
|
218
193
|
|
|
219
194
|
raise VALUE_TO_TEXT_WARNING if json_feature && value_not_text?
|
|
220
195
|
|
|
221
|
-
|
|
196
|
+
with_write_connection(@gate_class) do
|
|
222
197
|
@gate_class.transaction(requires_new: true) do
|
|
223
198
|
clear(feature) if clear_feature
|
|
224
199
|
delete(feature, gate)
|
|
@@ -243,7 +218,7 @@ module Flipper
|
|
|
243
218
|
end
|
|
244
219
|
|
|
245
220
|
def enable_multi(feature, gate, thing)
|
|
246
|
-
|
|
221
|
+
with_write_connection(@gate_class) do |connection|
|
|
247
222
|
begin
|
|
248
223
|
connection.transaction(requires_new: true) do
|
|
249
224
|
@gate_class.create! do |g|
|
|
@@ -299,6 +274,26 @@ module Flipper
|
|
|
299
274
|
model.connection_pool.with_connection(&block)
|
|
300
275
|
end
|
|
301
276
|
|
|
277
|
+
def with_write_connection(model = @feature_class, &block)
|
|
278
|
+
# Use Rails' built-in method to find the class that controls the connection
|
|
279
|
+
# This walks up the inheritance chain to find which class called connects_to
|
|
280
|
+
if model.respond_to?(:connection_class_for_self)
|
|
281
|
+
connection_class = model.connection_class_for_self
|
|
282
|
+
|
|
283
|
+
# Only use connected_to if this class actually has connects_to configured
|
|
284
|
+
# connection_class? returns true when connects_to was called on the class
|
|
285
|
+
if connection_class.respond_to?(:connection_class?) && connection_class.connection_class?
|
|
286
|
+
connection_class.connected_to(role: :writing) do
|
|
287
|
+
with_connection(model, &block)
|
|
288
|
+
end
|
|
289
|
+
else
|
|
290
|
+
with_connection(model, &block)
|
|
291
|
+
end
|
|
292
|
+
else
|
|
293
|
+
with_connection(model, &block)
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
302
297
|
def warned_about_value_not_text?
|
|
303
298
|
return @warned_about_value_not_text if defined?(@warned_about_value_not_text)
|
|
304
299
|
@warned_about_value_not_text = true
|
data/lib/flipper/version.rb
CHANGED
|
@@ -94,36 +94,36 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
|
|
|
94
94
|
|
|
95
95
|
context "ActiveRecord connection_pool" do
|
|
96
96
|
before do
|
|
97
|
-
|
|
97
|
+
clear_active_connections!
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
context "#features" do
|
|
101
101
|
it "does not hold onto connections" do
|
|
102
|
-
expect(
|
|
102
|
+
expect(active_connections?).to be(false)
|
|
103
103
|
subject.features
|
|
104
|
-
expect(
|
|
104
|
+
expect(active_connections?).to be(false)
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
it "does not release previously held connection" do
|
|
108
108
|
ActiveRecord::Base.connection # establish a new connection
|
|
109
|
-
expect(
|
|
109
|
+
expect(active_connections?).to be(true)
|
|
110
110
|
subject.features
|
|
111
|
-
expect(
|
|
111
|
+
expect(active_connections?).to be(true)
|
|
112
112
|
end
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
context "#get_all" do
|
|
116
116
|
it "does not hold onto connections" do
|
|
117
|
-
expect(
|
|
117
|
+
expect(active_connections?).to be(false)
|
|
118
118
|
subject.get_all
|
|
119
|
-
expect(
|
|
119
|
+
expect(active_connections?).to be(false)
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
it "does not release previously held connection" do
|
|
123
123
|
ActiveRecord::Base.connection # establish a new connection
|
|
124
|
-
expect(
|
|
124
|
+
expect(active_connections?).to be(true)
|
|
125
125
|
subject.get_all
|
|
126
|
-
expect(
|
|
126
|
+
expect(active_connections?).to be(true)
|
|
127
127
|
end
|
|
128
128
|
end
|
|
129
129
|
|
|
@@ -131,24 +131,24 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
|
|
|
131
131
|
let(:feature) { Flipper::Feature.new(:search, subject) }
|
|
132
132
|
|
|
133
133
|
it "does not hold onto connections" do
|
|
134
|
-
expect(
|
|
134
|
+
expect(active_connections?).to be(false)
|
|
135
135
|
subject.add(feature)
|
|
136
|
-
expect(
|
|
136
|
+
expect(active_connections?).to be(false)
|
|
137
137
|
subject.remove(feature)
|
|
138
|
-
expect(
|
|
138
|
+
expect(active_connections?).to be(false)
|
|
139
139
|
subject.clear(feature)
|
|
140
|
-
expect(
|
|
140
|
+
expect(active_connections?).to be(false)
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
it "does not release previously held connection" do
|
|
144
144
|
ActiveRecord::Base.connection # establish a new connection
|
|
145
|
-
expect(
|
|
145
|
+
expect(active_connections?).to be(true)
|
|
146
146
|
subject.add(feature)
|
|
147
|
-
expect(
|
|
147
|
+
expect(active_connections?).to be(true)
|
|
148
148
|
subject.remove(feature)
|
|
149
|
-
expect(
|
|
149
|
+
expect(active_connections?).to be(true)
|
|
150
150
|
subject.clear(feature)
|
|
151
|
-
expect(
|
|
151
|
+
expect(active_connections?).to be(true)
|
|
152
152
|
end
|
|
153
153
|
end
|
|
154
154
|
|
|
@@ -156,16 +156,16 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
|
|
|
156
156
|
let(:feature) { Flipper::Feature.new(:search, subject) }
|
|
157
157
|
|
|
158
158
|
it "does not hold onto connections" do
|
|
159
|
-
expect(
|
|
159
|
+
expect(active_connections?).to be(false)
|
|
160
160
|
subject.get_multi([feature])
|
|
161
|
-
expect(
|
|
161
|
+
expect(active_connections?).to be(false)
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
it "does not release previously held connection" do
|
|
165
165
|
ActiveRecord::Base.connection # establish a new connection
|
|
166
|
-
expect(
|
|
166
|
+
expect(active_connections?).to be(true)
|
|
167
167
|
subject.get_multi([feature])
|
|
168
|
-
expect(
|
|
168
|
+
expect(active_connections?).to be(true)
|
|
169
169
|
end
|
|
170
170
|
end
|
|
171
171
|
|
|
@@ -174,20 +174,20 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
|
|
|
174
174
|
let(:gate) { feature.gate(:boolean)}
|
|
175
175
|
|
|
176
176
|
it "does not hold onto connections" do
|
|
177
|
-
expect(
|
|
177
|
+
expect(active_connections?).to be(false)
|
|
178
178
|
subject.enable(feature, gate, gate.wrap(true))
|
|
179
|
-
expect(
|
|
179
|
+
expect(active_connections?).to be(false)
|
|
180
180
|
subject.disable(feature, gate, gate.wrap(false))
|
|
181
|
-
expect(
|
|
181
|
+
expect(active_connections?).to be(false)
|
|
182
182
|
end
|
|
183
183
|
|
|
184
184
|
it "does not release previously held connection" do
|
|
185
185
|
ActiveRecord::Base.connection # establish a new connection
|
|
186
|
-
expect(
|
|
186
|
+
expect(active_connections?).to be(true)
|
|
187
187
|
subject.enable(feature, gate, gate.wrap(true))
|
|
188
|
-
expect(
|
|
188
|
+
expect(active_connections?).to be(true)
|
|
189
189
|
subject.disable(feature, gate, gate.wrap(false))
|
|
190
|
-
expect(
|
|
190
|
+
expect(active_connections?).to be(true)
|
|
191
191
|
end
|
|
192
192
|
end
|
|
193
193
|
|
|
@@ -196,20 +196,118 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
|
|
|
196
196
|
let(:gate) { feature.gate(:group) }
|
|
197
197
|
|
|
198
198
|
it "does not hold onto connections" do
|
|
199
|
-
expect(
|
|
199
|
+
expect(active_connections?).to be(false)
|
|
200
200
|
subject.enable(feature, gate, gate.wrap(:admin))
|
|
201
|
-
expect(
|
|
201
|
+
expect(active_connections?).to be(false)
|
|
202
202
|
subject.disable(feature, gate, gate.wrap(:admin))
|
|
203
|
-
expect(
|
|
203
|
+
expect(active_connections?).to be(false)
|
|
204
204
|
end
|
|
205
205
|
|
|
206
206
|
it "does not release previously held connection" do
|
|
207
207
|
ActiveRecord::Base.connection # establish a new connection
|
|
208
|
-
expect(
|
|
208
|
+
expect(active_connections?).to be(true)
|
|
209
209
|
subject.enable(feature, gate, gate.wrap(:admin))
|
|
210
|
-
expect(
|
|
210
|
+
expect(active_connections?).to be(true)
|
|
211
211
|
subject.disable(feature, gate, gate.wrap(:admin))
|
|
212
|
-
expect(
|
|
212
|
+
expect(active_connections?).to be(true)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
if ActiveRecord.version >= Gem::Version.new('7.1')
|
|
218
|
+
context 'with read/write roles' do
|
|
219
|
+
before do
|
|
220
|
+
skip "connected_to with roles is not supported on #{config['adapter']}" if config["adapter"] == "sqlite3"
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
let(:abstract_class) do
|
|
224
|
+
# Create a named abstract class (Rails requires names for connects_to)
|
|
225
|
+
klass = Class.new(ActiveRecord::Base) do
|
|
226
|
+
self.abstract_class = true
|
|
227
|
+
end
|
|
228
|
+
stub_const('TestApplicationRecord', klass)
|
|
229
|
+
|
|
230
|
+
# Now configure connects_to with the same database for both roles
|
|
231
|
+
# In production, these would be different (primary/replica)
|
|
232
|
+
klass.connects_to database: {
|
|
233
|
+
writing: config,
|
|
234
|
+
reading: config
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
klass
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
after do
|
|
241
|
+
# Disconnect role-based connections to avoid interfering with database cleanup
|
|
242
|
+
clear_all_connections!
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
let(:feature_class) do
|
|
246
|
+
klass = Class.new(abstract_class) do
|
|
247
|
+
self.table_name = 'flipper_features'
|
|
248
|
+
validates :key, presence: true
|
|
249
|
+
end
|
|
250
|
+
stub_const('TestFeature', klass)
|
|
251
|
+
klass
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
let(:gate_class) do
|
|
255
|
+
klass = Class.new(abstract_class) do
|
|
256
|
+
self.table_name = 'flipper_gates'
|
|
257
|
+
end
|
|
258
|
+
stub_const('TestGate', klass)
|
|
259
|
+
klass
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
let(:adapter_with_roles) do
|
|
263
|
+
described_class.new(
|
|
264
|
+
feature_class: feature_class,
|
|
265
|
+
gate_class: gate_class
|
|
266
|
+
)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
it 'can perform write operations when forced to reading role' do
|
|
270
|
+
abstract_class.connected_to(role: :reading) do
|
|
271
|
+
flipper = Flipper.new(adapter_with_roles)
|
|
272
|
+
|
|
273
|
+
feature = flipper[:test_feature]
|
|
274
|
+
expect { feature.enable }.not_to raise_error
|
|
275
|
+
expect(feature.enabled?).to be(true)
|
|
276
|
+
expect { feature.disable }.not_to raise_error
|
|
277
|
+
expect(feature.enabled?).to be(false)
|
|
278
|
+
|
|
279
|
+
feature = flipper[:actor_test]
|
|
280
|
+
actor = Struct.new(:flipper_id).new(123)
|
|
281
|
+
expect { feature.enable_actor(actor) }.not_to raise_error
|
|
282
|
+
expect(feature.enabled?(actor)).to be(true)
|
|
283
|
+
expect { feature.disable_actor(actor) }.not_to raise_error
|
|
284
|
+
expect(feature.enabled?(actor)).to be(false)
|
|
285
|
+
|
|
286
|
+
feature = flipper[:gate_test]
|
|
287
|
+
expect { feature.enable_percentage_of_time(50) }.not_to raise_error
|
|
288
|
+
expect { feature.disable_percentage_of_time }.not_to raise_error
|
|
289
|
+
feature.enable
|
|
290
|
+
expect { feature.remove }.not_to raise_error
|
|
291
|
+
|
|
292
|
+
feature = flipper[:expression_test]
|
|
293
|
+
expression = Flipper.property(:plan).eq("premium")
|
|
294
|
+
expect { feature.enable_expression(expression) }.not_to raise_error
|
|
295
|
+
expect(feature.expression).to eq(expression)
|
|
296
|
+
expect { feature.disable_expression }.not_to raise_error
|
|
297
|
+
expect(feature.expression).to be_nil
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it 'does not hold onto connections during write operations' do
|
|
302
|
+
clear_active_connections!
|
|
303
|
+
|
|
304
|
+
abstract_class.connected_to(role: :reading) do
|
|
305
|
+
flipper = Flipper.new(adapter_with_roles)
|
|
306
|
+
feature = flipper[:connection_test]
|
|
307
|
+
|
|
308
|
+
feature.enable
|
|
309
|
+
expect(active_connections?).to be(false)
|
|
310
|
+
end
|
|
213
311
|
end
|
|
214
312
|
end
|
|
215
313
|
end
|
|
@@ -265,4 +363,19 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
|
|
|
265
363
|
end
|
|
266
364
|
end
|
|
267
365
|
end
|
|
366
|
+
|
|
367
|
+
def active_connections?
|
|
368
|
+
method = ActiveRecord::Base.connection_handler.method(:active_connections?)
|
|
369
|
+
method.arity == 0 ? method.call : method.call(:all)
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def clear_active_connections!
|
|
373
|
+
method = ActiveRecord::Base.connection_handler.method(:clear_active_connections!)
|
|
374
|
+
method.arity == 0 ? method.call : method.call(:all)
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
def clear_all_connections!
|
|
378
|
+
method = ActiveRecord::Base.connection_handler.method(:clear_all_connections!)
|
|
379
|
+
method.arity == 0 ? method.call : method.call(:all)
|
|
380
|
+
end
|
|
268
381
|
end
|
|
@@ -47,8 +47,16 @@ class ActiveRecordTest < MiniTest::Test
|
|
|
47
47
|
ActiveRecord::Base.table_name_prefix = :foo_
|
|
48
48
|
ActiveRecord::Base.table_name_suffix = :_bar
|
|
49
49
|
|
|
50
|
+
# Remove constants so they get redefined with new prefix/suffix
|
|
51
|
+
Flipper::Adapters::ActiveRecord.send(:remove_const, :Model) if Flipper::Adapters::ActiveRecord.const_defined?(:Model)
|
|
52
|
+
Flipper::Adapters::ActiveRecord.send(:remove_const, :Feature) if Flipper::Adapters::ActiveRecord.const_defined?(:Feature)
|
|
53
|
+
Flipper::Adapters::ActiveRecord.send(:remove_const, :Gate) if Flipper::Adapters::ActiveRecord.const_defined?(:Gate)
|
|
50
54
|
Flipper::Adapters.send(:remove_const, :ActiveRecord)
|
|
55
|
+
|
|
51
56
|
load("flipper/adapters/active_record.rb")
|
|
57
|
+
load("flipper/adapters/active_record/model.rb")
|
|
58
|
+
load("flipper/adapters/active_record/feature.rb")
|
|
59
|
+
load("flipper/adapters/active_record/gate.rb")
|
|
52
60
|
|
|
53
61
|
assert_equal "foo_flipper_features_bar", Flipper::Adapters::ActiveRecord::Feature.table_name
|
|
54
62
|
assert_equal "foo_flipper_gates_bar", Flipper::Adapters::ActiveRecord::Gate.table_name
|
|
@@ -57,7 +65,15 @@ class ActiveRecordTest < MiniTest::Test
|
|
|
57
65
|
ActiveRecord::Base.table_name_prefix = ""
|
|
58
66
|
ActiveRecord::Base.table_name_suffix = ""
|
|
59
67
|
|
|
68
|
+
# Remove constants so they get redefined with reset prefix/suffix
|
|
69
|
+
Flipper::Adapters::ActiveRecord.send(:remove_const, :Model) if Flipper::Adapters::ActiveRecord.const_defined?(:Model)
|
|
70
|
+
Flipper::Adapters::ActiveRecord.send(:remove_const, :Feature) if Flipper::Adapters::ActiveRecord.const_defined?(:Feature)
|
|
71
|
+
Flipper::Adapters::ActiveRecord.send(:remove_const, :Gate) if Flipper::Adapters::ActiveRecord.const_defined?(:Gate)
|
|
60
72
|
Flipper::Adapters.send(:remove_const, :ActiveRecord)
|
|
73
|
+
|
|
61
74
|
load("flipper/adapters/active_record.rb")
|
|
75
|
+
load("flipper/adapters/active_record/model.rb")
|
|
76
|
+
load("flipper/adapters/active_record/feature.rb")
|
|
77
|
+
load("flipper/adapters/active_record/gate.rb")
|
|
62
78
|
end
|
|
63
79
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: flipper-active_record
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- John Nunemaker
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-02-26 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: flipper
|
|
@@ -15,14 +16,14 @@ dependencies:
|
|
|
15
16
|
requirements:
|
|
16
17
|
- - "~>"
|
|
17
18
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 1.
|
|
19
|
+
version: 1.4.0
|
|
19
20
|
type: :runtime
|
|
20
21
|
prerelease: false
|
|
21
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
23
|
requirements:
|
|
23
24
|
- - "~>"
|
|
24
25
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 1.
|
|
26
|
+
version: 1.4.0
|
|
26
27
|
- !ruby/object:Gem::Dependency
|
|
27
28
|
name: activerecord
|
|
28
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -43,6 +44,7 @@ dependencies:
|
|
|
43
44
|
- - "<"
|
|
44
45
|
- !ruby/object:Gem::Version
|
|
45
46
|
version: '9'
|
|
47
|
+
description:
|
|
46
48
|
email: support@flippercloud.io
|
|
47
49
|
executables: []
|
|
48
50
|
extensions: []
|
|
@@ -59,6 +61,9 @@ files:
|
|
|
59
61
|
- flipper-active_record.gemspec
|
|
60
62
|
- lib/flipper-active_record.rb
|
|
61
63
|
- lib/flipper/adapters/active_record.rb
|
|
64
|
+
- lib/flipper/adapters/active_record/feature.rb
|
|
65
|
+
- lib/flipper/adapters/active_record/gate.rb
|
|
66
|
+
- lib/flipper/adapters/active_record/model.rb
|
|
62
67
|
- lib/flipper/version.rb
|
|
63
68
|
- lib/generators/flipper/active_record_generator.rb
|
|
64
69
|
- lib/generators/flipper/templates/migration.erb
|
|
@@ -73,8 +78,9 @@ metadata:
|
|
|
73
78
|
homepage_uri: https://www.flippercloud.io
|
|
74
79
|
source_code_uri: https://github.com/flippercloud/flipper
|
|
75
80
|
bug_tracker_uri: https://github.com/flippercloud/flipper/issues
|
|
76
|
-
changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.
|
|
81
|
+
changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.4.0
|
|
77
82
|
funding_uri: https://github.com/sponsors/flippercloud
|
|
83
|
+
post_install_message:
|
|
78
84
|
rdoc_options: []
|
|
79
85
|
require_paths:
|
|
80
86
|
- lib
|
|
@@ -89,9 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
89
95
|
- !ruby/object:Gem::Version
|
|
90
96
|
version: '0'
|
|
91
97
|
requirements: []
|
|
92
|
-
rubygems_version: 3.
|
|
98
|
+
rubygems_version: 3.5.22
|
|
99
|
+
signing_key:
|
|
93
100
|
specification_version: 4
|
|
94
101
|
summary: ActiveRecord feature flag adapter for Flipper
|
|
95
|
-
test_files:
|
|
96
|
-
- spec/flipper/adapters/active_record_spec.rb
|
|
97
|
-
- test/adapters/active_record_test.rb
|
|
102
|
+
test_files: []
|