flipper-active_record 1.3.4 → 1.4.2

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: ae15abe1a25ef415ec5f7783b24192ae52cbf86b6d8e8026a7b23d3182db2ea3
4
- data.tar.gz: 92c793efbd0539545f73d363f61df2f3a43d949aafb0bb303ecb5d8a747e660a
3
+ metadata.gz: f251eeb1ae6e73d21f21c239cd933d954ef39072cdb5014af3ae7e61e821cfbd
4
+ data.tar.gz: 46c6c7b74fee1d6d6b5ee6f9b859161949a79dbe808145a1126cfea2177fc287
5
5
  SHA512:
6
- metadata.gz: a01ae2b84eea1af1a46ed86a0727a38418ec88682fddf0e8829e340f39e368adf7e3451e07b05efc423d874cc6bf70910bfc7afe61267db84c6e8ef90d6f1764
7
- data.tar.gz: 280adedbab88143432826be99f65e17673f9bc0012ddb4c89392b32c6dd2c6ec9ce71a68bf1f79dce2347a631afc5d0f3804092ddbd2d6ef6906fb2af6142534
6
+ metadata.gz: 712df678bfdad895ebe0130a008968a8f0cbc951acc847f0cb82870137fecb08ad3f836d29c53fcc008dafa2ca30539f8fdaf22fb363e2980e40286ab1e1ba75
7
+ data.tar.gz: 6d4b9665760bec901ab35e61c8eb284b8d79368adc3152f8792e3290ca7c81b5a94515d633e17eaceae5499b1fd3c73192fd34d31a2a3d4e29c3b32a62b56b14
@@ -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
@@ -0,0 +1,9 @@
1
+ module Flipper
2
+ module Adapters
3
+ class ActiveRecord
4
+ class Model < ::ActiveRecord::Base
5
+ self.abstract_class = true
6
+ end
7
+ end
8
+ end
9
+ end
@@ -2,46 +2,17 @@ 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
- # Abstract base class for internal models
13
- class Model < ::ActiveRecord::Base
14
- self.abstract_class = true
15
- end
16
-
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
24
-
25
- has_many :gates, foreign_key: "feature_key", primary_key: "key"
26
-
27
- validates :key, presence: true
28
- end
29
-
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
37
-
38
- validates :feature_key, presence: true
39
- validates :key, presence: true
40
- end
41
- end
42
-
43
14
  VALUE_TO_TEXT_WARNING = <<-EOS
44
- Your database needs migrated to use the latest Flipper features.
15
+ Your database needs to be migrated to use the latest Flipper features.
45
16
  Run `rails generate flipper:update` and `rails db:migrate`.
46
17
  EOS
47
18
 
@@ -59,10 +30,8 @@ module Flipper
59
30
  # can roll your own tables and what not, if you so desire.
60
31
  def initialize(options = {})
61
32
  @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?
33
+ @feature_class = options.fetch(:feature_class) { Flipper::Adapters::ActiveRecord::Feature }
34
+ @gate_class = options.fetch(:gate_class) { Flipper::Adapters::ActiveRecord::Gate }
66
35
  end
67
36
 
68
37
  # Public: The set of known features.
@@ -72,7 +41,7 @@ module Flipper
72
41
 
73
42
  # Public: Adds a feature to the set of known features.
74
43
  def add(feature)
75
- with_connection(@feature_class) do
44
+ with_write_connection(@feature_class) do
76
45
  @feature_class.transaction(requires_new: true) do
77
46
  begin
78
47
  # race condition, but add is only used by enable/disable which happen
@@ -91,7 +60,7 @@ module Flipper
91
60
 
92
61
  # Public: Removes a feature from the set of known features.
93
62
  def remove(feature)
94
- with_connection(@feature_class) do
63
+ with_write_connection(@feature_class) do
95
64
  @feature_class.transaction do
96
65
  @feature_class.where(key: feature.key).destroy_all
97
66
  clear(feature)
@@ -102,7 +71,7 @@ module Flipper
102
71
 
103
72
  # Public: Clears the gate values for a feature.
104
73
  def clear(feature)
105
- with_connection(@gate_class) { @gate_class.where(feature_key: feature.key).destroy_all }
74
+ with_write_connection(@gate_class) { @gate_class.where(feature_key: feature.key).destroy_all }
106
75
  true
107
76
  end
108
77
 
@@ -131,7 +100,7 @@ module Flipper
131
100
  end
132
101
  end
133
102
 
134
- def get_all
103
+ def get_all(**kwargs)
135
104
  with_connection(@feature_class) do |connection|
136
105
  # query the gates from the db in a single query
137
106
  features = ::Arel::Table.new(@feature_class.table_name.to_sym)
@@ -154,6 +123,7 @@ module Flipper
154
123
  features.each do |feature|
155
124
  result[feature.key] = result_for_gates(feature, grouped_gates[feature.key])
156
125
  end
126
+ result.default_proc = nil
157
127
  result
158
128
  end
159
129
  end
@@ -196,9 +166,11 @@ module Flipper
196
166
  when :integer
197
167
  set(feature, gate, thing)
198
168
  when :json
199
- delete(feature, gate)
169
+ with_write_connection(@gate_class) do
170
+ delete(feature, gate)
171
+ end
200
172
  when :set
201
- with_connection(@gate_class) do
173
+ with_write_connection(@gate_class) do
202
174
  @gate_class.where(feature_key: feature.key, key: gate.key, value: thing.value).destroy_all
203
175
  end
204
176
  else
@@ -221,7 +193,7 @@ module Flipper
221
193
 
222
194
  raise VALUE_TO_TEXT_WARNING if json_feature && value_not_text?
223
195
 
224
- with_connection(@gate_class) do
196
+ with_write_connection(@gate_class) do
225
197
  @gate_class.transaction(requires_new: true) do
226
198
  clear(feature) if clear_feature
227
199
  delete(feature, gate)
@@ -246,7 +218,7 @@ module Flipper
246
218
  end
247
219
 
248
220
  def enable_multi(feature, gate, thing)
249
- with_connection(@gate_class) do |connection|
221
+ with_write_connection(@gate_class) do |connection|
250
222
  begin
251
223
  connection.transaction(requires_new: true) do
252
224
  @gate_class.create! do |g|
@@ -289,15 +261,43 @@ module Flipper
289
261
  # Check if value column is text instead of string
290
262
  # See https://github.com/flippercloud/flipper/pull/692
291
263
  def value_not_text?
292
- @gate_class.column_for_attribute(:value).type != :text
264
+ with_connection(@gate_class) do |connection|
265
+ @gate_class.column_for_attribute(:value).type != :text
266
+ end
293
267
  rescue ::ActiveRecord::ActiveRecordError => error
294
268
  # If the table doesn't exist, the column doesn't exist either
295
269
  warn "#{error.message}. You likely need to run `rails g flipper:active_record` and/or `rails db:migrate`."
296
270
  end
297
271
 
298
272
  def with_connection(model = @feature_class, &block)
273
+ warn VALUE_TO_TEXT_WARNING if !warned_about_value_not_text? && value_not_text?
299
274
  model.connection_pool.with_connection(&block)
300
275
  end
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
+
297
+ def warned_about_value_not_text?
298
+ return @warned_about_value_not_text if defined?(@warned_about_value_not_text)
299
+ @warned_about_value_not_text = true
300
+ end
301
301
  end
302
302
  end
303
303
  end
@@ -1,5 +1,5 @@
1
1
  module Flipper
2
- VERSION = '1.3.4'.freeze
2
+ VERSION = '1.4.2'.freeze
3
3
 
4
4
  REQUIRED_RUBY_VERSION = '2.6'.freeze
5
5
  NEXT_REQUIRED_RUBY_VERSION = '3.0'.freeze
@@ -94,36 +94,36 @@ RSpec.describe Flipper::Adapters::ActiveRecord do
94
94
 
95
95
  context "ActiveRecord connection_pool" do
96
96
  before do
97
- ActiveRecord::Base.connection_handler.clear_active_connections!
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(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
102
+ expect(active_connections?).to be(false)
103
103
  subject.features
104
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
109
+ expect(active_connections?).to be(true)
110
110
  subject.features
111
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
117
+ expect(active_connections?).to be(false)
118
118
  subject.get_all
119
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
124
+ expect(active_connections?).to be(true)
125
125
  subject.get_all
126
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
134
+ expect(active_connections?).to be(false)
135
135
  subject.add(feature)
136
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
136
+ expect(active_connections?).to be(false)
137
137
  subject.remove(feature)
138
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
138
+ expect(active_connections?).to be(false)
139
139
  subject.clear(feature)
140
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
145
+ expect(active_connections?).to be(true)
146
146
  subject.add(feature)
147
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
147
+ expect(active_connections?).to be(true)
148
148
  subject.remove(feature)
149
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
149
+ expect(active_connections?).to be(true)
150
150
  subject.clear(feature)
151
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
159
+ expect(active_connections?).to be(false)
160
160
  subject.get_multi([feature])
161
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
166
+ expect(active_connections?).to be(true)
167
167
  subject.get_multi([feature])
168
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
177
+ expect(active_connections?).to be(false)
178
178
  subject.enable(feature, gate, gate.wrap(true))
179
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
179
+ expect(active_connections?).to be(false)
180
180
  subject.disable(feature, gate, gate.wrap(false))
181
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
186
+ expect(active_connections?).to be(true)
187
187
  subject.enable(feature, gate, gate.wrap(true))
188
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
188
+ expect(active_connections?).to be(true)
189
189
  subject.disable(feature, gate, gate.wrap(false))
190
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
199
+ expect(active_connections?).to be(false)
200
200
  subject.enable(feature, gate, gate.wrap(:admin))
201
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
201
+ expect(active_connections?).to be(false)
202
202
  subject.disable(feature, gate, gate.wrap(:admin))
203
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(false)
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(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
208
+ expect(active_connections?).to be(true)
209
209
  subject.enable(feature, gate, gate.wrap(:admin))
210
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
210
+ expect(active_connections?).to be(true)
211
211
  subject.disable(feature, gate, gate.wrap(:admin))
212
- expect(ActiveRecord::Base.connection_handler.active_connections?).to be(true)
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.3.4
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 2025-03-03 00:00:00.000000000 Z
11
+ date: 2026-05-11 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.3.4
19
+ version: 1.4.2
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.3.4
26
+ version: 1.4.2
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.3.4
81
+ changelog_uri: https://github.com/flippercloud/flipper/releases/tag/v1.4.2
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.6.5
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: []