flipper-active_record 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/docs/active_record/README.md +158 -0
- data/examples/active_record/basic.rb +35 -0
- data/examples/active_record/internals.rb +123 -0
- data/flipper-active_record.gemspec +24 -0
- data/lib/flipper-active_record.rb +1 -0
- data/lib/flipper/adapters/active_record.rb +158 -0
- data/lib/flipper/version.rb +3 -0
- data/lib/generators/flipper/active_record_generator.rb +20 -0
- data/spec/flipper/adapters/active_record_spec.rb +29 -0
- data/test/generators/flipper/active_record_generator_test.rb +38 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b25aebfea175656f0350407f74bf953e0b7299ab
|
4
|
+
data.tar.gz: 897ead9429ae1558099308bd21445f32642348d8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 641ae8faae41d0cef4b8f011dff325d4edad00dedfbe4daff7a32f795505ff84b70bc48960f924464a288b667848b2ae4f2aab13a39b97aecbcf2dcc28e5449b
|
7
|
+
data.tar.gz: 41253500ac648a0322ffd3a1e278dac7f1cc6ea5d5ac7d3e6c02eab23740952b8d91fe149b701bafcbec092d2c01d84fe4491893df39d9cadb677709e6ef6324
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# Flipper ActiveRecord
|
2
|
+
|
3
|
+
An ActiveRecord adapter for [Flipper](https://github.com/jnunemaker/flipper).
|
4
|
+
|
5
|
+
Supported Active Record versions:
|
6
|
+
|
7
|
+
* 3.2.x
|
8
|
+
* 4.2.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:
|
27
|
+
|
28
|
+
$ rails g flipper:active_record
|
29
|
+
|
30
|
+
Once you have created and executed the migration, you can use the active record adapter like so:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
require 'flipper/adapters/active_record'
|
34
|
+
adapter = Flipper::Adapters::ActiveRecord.new
|
35
|
+
flipper = Flipper.new(adapter)
|
36
|
+
# profit...
|
37
|
+
```
|
38
|
+
|
39
|
+
## Internals
|
40
|
+
|
41
|
+
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.
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
require 'flipper/adapters/active_record'
|
45
|
+
adapter = Flipper::Adapters::ActiveRecord.new
|
46
|
+
flipper = Flipper.new(adapter)
|
47
|
+
|
48
|
+
# Register a few groups.
|
49
|
+
Flipper.register(:admins) { |thing| thing.admin? }
|
50
|
+
Flipper.register(:early_access) { |thing| thing.early_access? }
|
51
|
+
|
52
|
+
# Create a user class that has flipper_id instance method.
|
53
|
+
User = Struct.new(:flipper_id)
|
54
|
+
|
55
|
+
flipper[:stats].enable
|
56
|
+
flipper[:stats].enable_group :admins
|
57
|
+
flipper[:stats].enable_group :early_access
|
58
|
+
flipper[:stats].enable_actor User.new('25')
|
59
|
+
flipper[:stats].enable_actor User.new('90')
|
60
|
+
flipper[:stats].enable_actor User.new('180')
|
61
|
+
flipper[:stats].enable_percentage_of_time 15
|
62
|
+
flipper[:stats].enable_percentage_of_actors 45
|
63
|
+
|
64
|
+
flipper[:search].enable
|
65
|
+
|
66
|
+
puts 'all rows in features table'
|
67
|
+
pp Flipper::Adapters::ActiveRecord::Feature.all
|
68
|
+
# [#<Flipper::Adapters::ActiveRecord::Feature:0x007fd259b47110
|
69
|
+
# id: 1,
|
70
|
+
# key: "stats",
|
71
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
72
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
73
|
+
# #<Flipper::Adapters::ActiveRecord::Feature:0x007fd259b46cd8
|
74
|
+
# id: 2,
|
75
|
+
# key: "search",
|
76
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
77
|
+
# updated_at: 2015-12-21 16:26:29 UTC>]
|
78
|
+
puts
|
79
|
+
|
80
|
+
puts 'all rows in gates table'
|
81
|
+
pp Flipper::Adapters::ActiveRecord::Gate.all
|
82
|
+
# [#<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0f0f8
|
83
|
+
# id: 1,
|
84
|
+
# feature_key: "stats",
|
85
|
+
# key: "boolean",
|
86
|
+
# value: "true",
|
87
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
88
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
89
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0ebd0
|
90
|
+
# id: 2,
|
91
|
+
# feature_key: "stats",
|
92
|
+
# key: "groups",
|
93
|
+
# value: "admins",
|
94
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
95
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
96
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0e748
|
97
|
+
# id: 3,
|
98
|
+
# feature_key: "stats",
|
99
|
+
# key: "groups",
|
100
|
+
# value: "early_access",
|
101
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
102
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
103
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0e568
|
104
|
+
# id: 4,
|
105
|
+
# feature_key: "stats",
|
106
|
+
# key: "actors",
|
107
|
+
# value: "25",
|
108
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
109
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
110
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0e0b8
|
111
|
+
# id: 5,
|
112
|
+
# feature_key: "stats",
|
113
|
+
# key: "actors",
|
114
|
+
# value: "90",
|
115
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
116
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
117
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0da50
|
118
|
+
# id: 6,
|
119
|
+
# feature_key: "stats",
|
120
|
+
# key: "actors",
|
121
|
+
# value: "180",
|
122
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
123
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
124
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0d3c0
|
125
|
+
# id: 7,
|
126
|
+
# feature_key: "stats",
|
127
|
+
# key: "percentage_of_time",
|
128
|
+
# value: "15",
|
129
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
130
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
131
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0cdf8
|
132
|
+
# id: 8,
|
133
|
+
# feature_key: "stats",
|
134
|
+
# key: "percentage_of_actors",
|
135
|
+
# value: "45",
|
136
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
137
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
138
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0cbf0
|
139
|
+
# id: 9,
|
140
|
+
# feature_key: "search",
|
141
|
+
# key: "boolean",
|
142
|
+
# value: "true",
|
143
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
144
|
+
# updated_at: 2015-12-21 16:26:29 UTC>]
|
145
|
+
puts
|
146
|
+
|
147
|
+
puts 'flipper get of feature'
|
148
|
+
pp adapter.get(flipper[:stats])
|
149
|
+
# flipper get of feature
|
150
|
+
```
|
151
|
+
|
152
|
+
## Contributing
|
153
|
+
|
154
|
+
1. Fork it
|
155
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
156
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
157
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
158
|
+
5. Create new Pull Request
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
root_path = Pathname(__FILE__).dirname.join('..').expand_path
|
5
|
+
lib_path = root_path.join('lib')
|
6
|
+
$:.unshift(lib_path)
|
7
|
+
|
8
|
+
require 'active_record'
|
9
|
+
ActiveRecord::Base.establish_connection({
|
10
|
+
adapter: 'sqlite3',
|
11
|
+
database: ':memory:',
|
12
|
+
})
|
13
|
+
|
14
|
+
require 'generators/flipper/templates/migration'
|
15
|
+
CreateFlipperTables.up
|
16
|
+
|
17
|
+
require 'flipper/adapters/active_record'
|
18
|
+
adapter = Flipper::Adapters::ActiveRecord.new
|
19
|
+
flipper = Flipper.new(adapter)
|
20
|
+
|
21
|
+
flipper[:stats].enable
|
22
|
+
|
23
|
+
if flipper[:stats].enabled?
|
24
|
+
puts "Enabled!"
|
25
|
+
else
|
26
|
+
puts "Disabled!"
|
27
|
+
end
|
28
|
+
|
29
|
+
flipper[:stats].disable
|
30
|
+
|
31
|
+
if flipper[:stats].enabled?
|
32
|
+
puts "Enabled!"
|
33
|
+
else
|
34
|
+
puts "Disabled!"
|
35
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'pathname'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
root_path = Pathname(__FILE__).dirname.join('..').expand_path
|
6
|
+
lib_path = root_path.join('lib')
|
7
|
+
$:.unshift(lib_path)
|
8
|
+
|
9
|
+
require 'active_record'
|
10
|
+
ActiveRecord::Base.establish_connection({
|
11
|
+
adapter: 'sqlite3',
|
12
|
+
database: ':memory:',
|
13
|
+
})
|
14
|
+
|
15
|
+
require 'generators/flipper/templates/migration'
|
16
|
+
CreateFlipperTables.up
|
17
|
+
|
18
|
+
require 'flipper/adapters/active_record'
|
19
|
+
adapter = Flipper::Adapters::ActiveRecord.new
|
20
|
+
flipper = Flipper.new(adapter)
|
21
|
+
|
22
|
+
# Register a few groups.
|
23
|
+
Flipper.register(:admins) { |thing| thing.admin? }
|
24
|
+
Flipper.register(:early_access) { |thing| thing.early_access? }
|
25
|
+
|
26
|
+
# Create a user class that has flipper_id instance method.
|
27
|
+
User = Struct.new(:flipper_id)
|
28
|
+
|
29
|
+
flipper[:stats].enable
|
30
|
+
flipper[:stats].enable_group :admins
|
31
|
+
flipper[:stats].enable_group :early_access
|
32
|
+
flipper[:stats].enable_actor User.new('25')
|
33
|
+
flipper[:stats].enable_actor User.new('90')
|
34
|
+
flipper[:stats].enable_actor User.new('180')
|
35
|
+
flipper[:stats].enable_percentage_of_time 15
|
36
|
+
flipper[:stats].enable_percentage_of_actors 45
|
37
|
+
|
38
|
+
flipper[:search].enable
|
39
|
+
|
40
|
+
puts 'all rows in features table'
|
41
|
+
pp Flipper::Adapters::ActiveRecord::Feature.all
|
42
|
+
# [#<Flipper::Adapters::ActiveRecord::Feature:0x007fd259b47110
|
43
|
+
# id: 1,
|
44
|
+
# key: "stats",
|
45
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
46
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
47
|
+
# #<Flipper::Adapters::ActiveRecord::Feature:0x007fd259b46cd8
|
48
|
+
# id: 2,
|
49
|
+
# key: "search",
|
50
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
51
|
+
# updated_at: 2015-12-21 16:26:29 UTC>]
|
52
|
+
puts
|
53
|
+
|
54
|
+
puts 'all rows in gates table'
|
55
|
+
pp Flipper::Adapters::ActiveRecord::Gate.all
|
56
|
+
# [#<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0f0f8
|
57
|
+
# id: 1,
|
58
|
+
# feature_key: "stats",
|
59
|
+
# key: "boolean",
|
60
|
+
# value: "true",
|
61
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
62
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
63
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0ebd0
|
64
|
+
# id: 2,
|
65
|
+
# feature_key: "stats",
|
66
|
+
# key: "groups",
|
67
|
+
# value: "admins",
|
68
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
69
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
70
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0e748
|
71
|
+
# id: 3,
|
72
|
+
# feature_key: "stats",
|
73
|
+
# key: "groups",
|
74
|
+
# value: "early_access",
|
75
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
76
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
77
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0e568
|
78
|
+
# id: 4,
|
79
|
+
# feature_key: "stats",
|
80
|
+
# key: "actors",
|
81
|
+
# value: "25",
|
82
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
83
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
84
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0e0b8
|
85
|
+
# id: 5,
|
86
|
+
# feature_key: "stats",
|
87
|
+
# key: "actors",
|
88
|
+
# value: "90",
|
89
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
90
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
91
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0da50
|
92
|
+
# id: 6,
|
93
|
+
# feature_key: "stats",
|
94
|
+
# key: "actors",
|
95
|
+
# value: "180",
|
96
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
97
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
98
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0d3c0
|
99
|
+
# id: 7,
|
100
|
+
# feature_key: "stats",
|
101
|
+
# key: "percentage_of_time",
|
102
|
+
# value: "15",
|
103
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
104
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
105
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0cdf8
|
106
|
+
# id: 8,
|
107
|
+
# feature_key: "stats",
|
108
|
+
# key: "percentage_of_actors",
|
109
|
+
# value: "45",
|
110
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
111
|
+
# updated_at: 2015-12-21 16:26:29 UTC>,
|
112
|
+
# #<Flipper::Adapters::ActiveRecord::Gate:0x007fd259b0cbf0
|
113
|
+
# id: 9,
|
114
|
+
# feature_key: "search",
|
115
|
+
# key: "boolean",
|
116
|
+
# value: "true",
|
117
|
+
# created_at: 2015-12-21 16:26:29 UTC,
|
118
|
+
# updated_at: 2015-12-21 16:26:29 UTC>]
|
119
|
+
puts
|
120
|
+
|
121
|
+
puts 'flipper get of feature'
|
122
|
+
pp adapter.get(flipper[:stats])
|
123
|
+
# flipper get of feature
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/flipper/version', __FILE__)
|
3
|
+
|
4
|
+
flipper_mongo_files = lambda { |file|
|
5
|
+
file =~ /active_record/
|
6
|
+
}
|
7
|
+
|
8
|
+
Gem::Specification.new do |gem|
|
9
|
+
gem.authors = ["John Nunemaker"]
|
10
|
+
gem.email = ["nunemaker@gmail.com"]
|
11
|
+
gem.summary = "ActiveRecord adapter for Flipper"
|
12
|
+
gem.description = "ActiveRecord adapter for Flipper"
|
13
|
+
gem.license = "MIT"
|
14
|
+
gem.homepage = "https://github.com/jnunemaker/flipper"
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split("\n").select(&flipper_mongo_files) + ["lib/flipper/version.rb"]
|
17
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n").select(&flipper_mongo_files)
|
18
|
+
gem.name = "flipper-active_record"
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
gem.version = Flipper::VERSION
|
21
|
+
|
22
|
+
gem.add_dependency 'flipper', "~> #{Flipper::VERSION}"
|
23
|
+
gem.add_dependency 'activerecord', ">= 3.2", "< 5"
|
24
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'flipper/adapters/active_record'
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'flipper'
|
3
|
+
require 'active_record'
|
4
|
+
|
5
|
+
module Flipper
|
6
|
+
module Adapters
|
7
|
+
class ActiveRecord
|
8
|
+
include Flipper::Adapter
|
9
|
+
|
10
|
+
# Private: Do not use outside of this adapter.
|
11
|
+
class Feature < ::ActiveRecord::Base
|
12
|
+
self.table_name = "flipper_features"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Private: Do not use outside of this adapter.
|
16
|
+
class Gate < ::ActiveRecord::Base
|
17
|
+
self.table_name = "flipper_gates"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public: The name of the adapter.
|
21
|
+
attr_reader :name
|
22
|
+
|
23
|
+
# Public: Initialize a new ActiveRecord adapter instance.
|
24
|
+
#
|
25
|
+
# name - The Symbol name for this adapter. Optional (default :active_record)
|
26
|
+
# feature_class - The AR class responsible for the features table.
|
27
|
+
# gate_class - The AR class responsible for the gates table.
|
28
|
+
#
|
29
|
+
# Allowing the overriding of name is so you can differentiate multiple
|
30
|
+
# instances of this adapter from each other, if, for some reason, that is
|
31
|
+
# a thing you do.
|
32
|
+
#
|
33
|
+
# Allowing the overriding of the default feature/gate classes means you
|
34
|
+
# can roll your own tables and what not, if you so desire.
|
35
|
+
def initialize(options = {})
|
36
|
+
@name = options.fetch(:name, :active_record)
|
37
|
+
@feature_class = options.fetch(:feature_class) { Feature }
|
38
|
+
@gate_class = options.fetch(:gate_class) { Gate }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Public: The set of known features.
|
42
|
+
def features
|
43
|
+
@feature_class.select(:key).map(&:key).to_set
|
44
|
+
end
|
45
|
+
|
46
|
+
# Public: Adds a feature to the set of known features.
|
47
|
+
def add(feature)
|
48
|
+
attributes = {key: feature.key}
|
49
|
+
# race condition, but add is only used by enable/disable which happen
|
50
|
+
# super rarely, so it shouldn't matter in practice
|
51
|
+
@feature_class.where(attributes).first || @feature_class.create!(attributes)
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
# Public: Removes a feature from the set of known features.
|
56
|
+
def remove(feature)
|
57
|
+
@feature_class.transaction do
|
58
|
+
@feature_class.delete_all(key: feature.key)
|
59
|
+
clear(feature)
|
60
|
+
end
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
64
|
+
# Public: Clears the gate values for a feature.
|
65
|
+
def clear(feature)
|
66
|
+
@gate_class.delete_all(feature_key: feature.key)
|
67
|
+
true
|
68
|
+
end
|
69
|
+
|
70
|
+
# Public: Gets the values for all gates for a given feature.
|
71
|
+
#
|
72
|
+
# Returns a Hash of Flipper::Gate#key => value.
|
73
|
+
def get(feature)
|
74
|
+
result = {}
|
75
|
+
|
76
|
+
db_gates = @gate_class.where(feature_key: feature.key)
|
77
|
+
|
78
|
+
feature.gates.each do |gate|
|
79
|
+
result[gate.key] = case gate.data_type
|
80
|
+
when :boolean
|
81
|
+
if db_gate = db_gates.detect { |db_gate| db_gate.key == gate.key.to_s }
|
82
|
+
db_gate.value
|
83
|
+
end
|
84
|
+
when :integer
|
85
|
+
if db_gate = db_gates.detect { |db_gate| db_gate.key == gate.key.to_s }
|
86
|
+
db_gate.value
|
87
|
+
end
|
88
|
+
when :set
|
89
|
+
db_gates.select { |db_gate| db_gate.key == gate.key.to_s }.map(&:value).to_set
|
90
|
+
else
|
91
|
+
unsupported_data_type gate.data_type
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
result
|
96
|
+
end
|
97
|
+
|
98
|
+
# Public: Enables a gate for a given thing.
|
99
|
+
#
|
100
|
+
# feature - The Flipper::Feature for the gate.
|
101
|
+
# gate - The Flipper::Gate to disable.
|
102
|
+
# thing - The Flipper::Type being disabled for the gate.
|
103
|
+
#
|
104
|
+
# Returns true.
|
105
|
+
def enable(feature, gate, thing)
|
106
|
+
case gate.data_type
|
107
|
+
when :boolean, :integer
|
108
|
+
@gate_class.create!({
|
109
|
+
feature_key: feature.key,
|
110
|
+
key: gate.key,
|
111
|
+
value: thing.value.to_s,
|
112
|
+
})
|
113
|
+
when :set
|
114
|
+
@gate_class.create!({
|
115
|
+
feature_key: feature.key,
|
116
|
+
key: gate.key,
|
117
|
+
value: thing.value.to_s,
|
118
|
+
})
|
119
|
+
else
|
120
|
+
unsupported_data_type gate.data_type
|
121
|
+
end
|
122
|
+
|
123
|
+
true
|
124
|
+
end
|
125
|
+
|
126
|
+
# Public: Disables a gate for a given thing.
|
127
|
+
#
|
128
|
+
# feature - The Flipper::Feature for the gate.
|
129
|
+
# gate - The Flipper::Gate to disable.
|
130
|
+
# thing - The Flipper::Type being disabled for the gate.
|
131
|
+
#
|
132
|
+
# Returns true.
|
133
|
+
def disable(feature, gate, thing)
|
134
|
+
case gate.data_type
|
135
|
+
when :boolean
|
136
|
+
clear(feature)
|
137
|
+
when :integer
|
138
|
+
@gate_class.create!({
|
139
|
+
feature_key: feature.key,
|
140
|
+
key: gate.key,
|
141
|
+
value: thing.value.to_s,
|
142
|
+
})
|
143
|
+
when :set
|
144
|
+
@gate_class.delete_all(feature_key: feature.key, key: gate.key, value: thing.value)
|
145
|
+
else
|
146
|
+
unsupported_data_type gate.data_type
|
147
|
+
end
|
148
|
+
|
149
|
+
true
|
150
|
+
end
|
151
|
+
|
152
|
+
# Private
|
153
|
+
def unsupported_data_type(data_type)
|
154
|
+
raise "#{data_type} is not supported by this adapter"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "rails/generators/active_record"
|
2
|
+
|
3
|
+
module Flipper
|
4
|
+
module Generators
|
5
|
+
class ActiveRecordGenerator < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
desc "Generates migration for flipper tables"
|
8
|
+
|
9
|
+
source_paths << File.join(File.dirname(__FILE__), "templates")
|
10
|
+
|
11
|
+
def create_migration_file
|
12
|
+
migration_template "migration.rb", "db/migrate/create_flipper_tables.rb"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.next_migration_number(dirname)
|
16
|
+
::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'flipper/adapters/active_record'
|
3
|
+
require 'flipper/spec/shared_adapter_specs'
|
4
|
+
|
5
|
+
# Turn off migration logging for specs
|
6
|
+
ActiveRecord::Migration.verbose = false
|
7
|
+
|
8
|
+
require 'generators/flipper/templates/migration'
|
9
|
+
|
10
|
+
RSpec.describe Flipper::Adapters::ActiveRecord do
|
11
|
+
subject { described_class.new }
|
12
|
+
|
13
|
+
before(:all) do
|
14
|
+
ActiveRecord::Base.establish_connection({
|
15
|
+
adapter: "sqlite3",
|
16
|
+
database: ":memory:",
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
20
|
+
before(:each) do
|
21
|
+
CreateFlipperTables.up
|
22
|
+
end
|
23
|
+
|
24
|
+
after(:each) do
|
25
|
+
CreateFlipperTables.down
|
26
|
+
end
|
27
|
+
|
28
|
+
it_should_behave_like 'a flipper adapter'
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'active_record'
|
3
|
+
require 'rails/generators/test_case'
|
4
|
+
require 'generators/flipper/active_record_generator'
|
5
|
+
|
6
|
+
class FlipperActiveRecordGeneratorTest < Rails::Generators::TestCase
|
7
|
+
tests Flipper::Generators::ActiveRecordGenerator
|
8
|
+
destination File.expand_path("../../../../tmp", __FILE__)
|
9
|
+
setup :prepare_destination
|
10
|
+
|
11
|
+
def test_generates_migration
|
12
|
+
run_generator
|
13
|
+
assert_migration "db/migrate/create_flipper_tables.rb", <<-EOM
|
14
|
+
class CreateFlipperTables < ActiveRecord::Migration
|
15
|
+
def self.up
|
16
|
+
create_table :flipper_features do |t|
|
17
|
+
t.string :key, null: false
|
18
|
+
t.timestamps null: false
|
19
|
+
end
|
20
|
+
add_index :flipper_features, :key, unique: true
|
21
|
+
|
22
|
+
create_table :flipper_gates do |t|
|
23
|
+
t.string :feature_key, null: false
|
24
|
+
t.string :key, null: false
|
25
|
+
t.string :value
|
26
|
+
t.timestamps null: false
|
27
|
+
end
|
28
|
+
add_index :flipper_gates, [:feature_key, :key, :value], unique: true
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.down
|
32
|
+
drop_table :flipper_gates
|
33
|
+
drop_table :flipper_features
|
34
|
+
end
|
35
|
+
end
|
36
|
+
EOM
|
37
|
+
end
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flipper-active_record
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Nunemaker
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: flipper
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.7.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.7.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activerecord
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.2'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '5'
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '3.2'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '5'
|
47
|
+
description: ActiveRecord adapter for Flipper
|
48
|
+
email:
|
49
|
+
- nunemaker@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- docs/active_record/README.md
|
55
|
+
- examples/active_record/basic.rb
|
56
|
+
- examples/active_record/internals.rb
|
57
|
+
- flipper-active_record.gemspec
|
58
|
+
- lib/flipper-active_record.rb
|
59
|
+
- lib/flipper/adapters/active_record.rb
|
60
|
+
- lib/flipper/version.rb
|
61
|
+
- lib/generators/flipper/active_record_generator.rb
|
62
|
+
- spec/flipper/adapters/active_record_spec.rb
|
63
|
+
- test/generators/flipper/active_record_generator_test.rb
|
64
|
+
homepage: https://github.com/jnunemaker/flipper
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.4.5.1
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: ActiveRecord adapter for Flipper
|
88
|
+
test_files:
|
89
|
+
- spec/flipper/adapters/active_record_spec.rb
|
90
|
+
- test/generators/flipper/active_record_generator_test.rb
|