feature_setting 1.5.2 → 1.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +11 -2
- data/README.md +27 -6
- data/feature_setting.gemspec +2 -2
- data/lib/feature_setting/orm/active_record/fs_feature.rb +39 -14
- data/lib/feature_setting/orm/active_record/fs_setting.rb +57 -27
- data/lib/feature_setting/version.rb +1 -1
- data/lib/generators/feature_setting/install/templates/migrations/create_fs_tables.rb +6 -1
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 53ffa8db4e5e12eab93ef6a84df1d16c297459643d84139b3f34bf15eed7f88a
|
4
|
+
data.tar.gz: 9f88e1e4672bc51d4d1a739e510ffbc448448422870a2b14873318fe49710c44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbe6488bc9eb17cfb6812ce5be36b7d58368436938be2e18ef5105695412a2d4786852befedec892f4b72137a227a4166957bad89a0bedc4de6d8836c3f24f4e
|
7
|
+
data.tar.gz: 2753e2457b391937abd777ff998a574cf765052d7de782e52eba986b3d5b33c9561186aaf46fc0fe5070223afc9d02684d41e5401873f16e72ecbda13f4783df
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
env:
|
2
|
+
global:
|
3
|
+
- CC_TEST_REPORTER_ID=3cb479d83eec93856a43161ba46dbad5b8d2e4979a36754bfc07202277b7f1c6
|
1
4
|
language: ruby
|
2
|
-
|
3
|
-
-
|
5
|
+
before_script:
|
6
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
7
|
+
- chmod +x ./cc-test-reporter
|
8
|
+
- ./cc-test-reporter before-build
|
9
|
+
script:
|
10
|
+
- bundle exec rspec
|
11
|
+
after_script:
|
12
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/README.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
# feature_setting
|
2
2
|
|
3
|
-
[![Gem
|
3
|
+
[![Gem
|
4
|
+
Version](https://badge.fury.io/rb/feature_setting.svg)](http://badge.fury.io/rb/feature_setting)
|
5
|
+
[![Code
|
6
|
+
Climate](https://codeclimate.com/github/indrode/feature_setting/badges/gpa.svg)](https://codeclimate.com/github/indrode/feature_setting)
|
7
|
+
[![Test
|
8
|
+
Coverage](https://codeclimate.com/github/indrode/feature_setting/badges/coverage.svg)](https://codeclimate.com/github/indrode/feature_setting/coverage)
|
9
|
+
[![security](https://hakiri.io/github/indrode/feature_setting/master.svg)](https://hakiri.io/github/indrode/feature_setting/master) [![Build Status](https://travis-ci.org/indrode/feature_setting.svg?branch=master)](https://travis-ci.org/indrode/feature_setting)
|
4
10
|
|
5
11
|
This gem introduces the concept of "features" and "settings" to your Rails app. It provides an easy way to define such features and settings with default values right in your code and will persist them in the database.
|
6
12
|
|
@@ -63,6 +69,7 @@ class Features < FeatureSetting::Feature
|
|
63
69
|
init_features!
|
64
70
|
end
|
65
71
|
```
|
72
|
+
**Note:** You can call `init_features!(true)` to remove any existing features that are not defined anymore
|
66
73
|
|
67
74
|
For each key you have defined, a class method `keyname_enabled?` is generated. You can now do the following:
|
68
75
|
|
@@ -103,17 +110,23 @@ class Settings < FeatureSetting::Setting
|
|
103
110
|
end
|
104
111
|
```
|
105
112
|
|
113
|
+
**Note:** You can call `init_settings!(true)` to remove any existing settings that are not defined anymore
|
114
|
+
|
106
115
|
You can now do the following:
|
107
116
|
|
108
117
|
```ruby
|
109
118
|
Settings.setting_one # => 12300
|
110
119
|
Settings.setting_one = 2000
|
111
120
|
Settings.setting_one # => 2000
|
121
|
+
```
|
122
|
+
|
123
|
+
**NEW IN VERSION 1.6:** Hashes values can be updated individually and will not overwrite the entire hash:
|
124
|
+
```ruby
|
125
|
+
Settings.setting_five = { key1: 'another_value' }
|
126
|
+
=> setting_five: { key1: 'another_value', key2: 'value2' }
|
112
127
|
|
113
|
-
|
114
|
-
|
115
|
-
Settings.set!(:setting_one, 1000)
|
116
|
-
Settings.set!('setting_one', 1000)
|
128
|
+
Settings.setting_five = { key3: 'value3' }
|
129
|
+
=> setting_five: { key1: 'another_value', key2: 'value2', key3: 'value3' }
|
117
130
|
```
|
118
131
|
|
119
132
|
Default values for settings are defined in your class and current values are persisted in the database.
|
@@ -146,6 +159,14 @@ Features.defined_features
|
|
146
159
|
Settings.defined_settings
|
147
160
|
```
|
148
161
|
|
162
|
+
Cache settings or features:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
Features.cache_features!
|
166
|
+
Settings.cache_settings!
|
167
|
+
```
|
168
|
+
Note that a simple call to `Features.init_features!` or `Settings.init_settings!` respectively will remove caching.
|
169
|
+
|
149
170
|
You can create as many Setting or Feature classes as you desire. Here are some examples:
|
150
171
|
|
151
172
|
```ruby
|
@@ -171,7 +192,7 @@ Notes:
|
|
171
192
|
|
172
193
|
The MIT License (MIT)
|
173
194
|
|
174
|
-
Copyright (c) 2015, 2016 Indro De ([http://indrode.com](http://indrode.com))
|
195
|
+
Copyright (c) 2015, 2016, 2017, 2018, 2019 Indro De ([http://indrode.com](http://indrode.com))
|
175
196
|
|
176
197
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
177
198
|
|
data/feature_setting.gemspec
CHANGED
@@ -24,6 +24,6 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency 'rake', '>= 10.0'
|
25
25
|
spec.add_development_dependency 'rspec', '>= 3.0'
|
26
26
|
spec.add_development_dependency 'sqlite3'
|
27
|
-
spec.add_development_dependency 'byebug'
|
28
|
-
spec.add_development_dependency '
|
27
|
+
spec.add_development_dependency 'byebug'
|
28
|
+
spec.add_development_dependency 'simplecov'
|
29
29
|
end
|
@@ -31,21 +31,46 @@ module FeatureSetting
|
|
31
31
|
self.new.klass.to_s
|
32
32
|
end
|
33
33
|
|
34
|
-
def init_features!
|
34
|
+
def init_features!(remove_old_features = false)
|
35
35
|
features.each do |key, value|
|
36
36
|
self.create_with(key: key, enabled: value, klass: klass).find_or_create_by(klass: klass, key: key)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
define_singleton_method("enable_#{key}!") do
|
42
|
-
enable!(key)
|
43
|
-
end
|
44
|
-
define_singleton_method("disable_#{key}!") do
|
45
|
-
disable!(key)
|
46
|
-
end
|
37
|
+
define_checker_method(key)
|
38
|
+
define_enabler_method(key)
|
39
|
+
define_disabler_method(key)
|
47
40
|
end
|
48
|
-
remove_old_features!
|
41
|
+
remove_old_features! if remove_old_features
|
42
|
+
end
|
43
|
+
|
44
|
+
def cache_features!
|
45
|
+
features.each do |key, value|
|
46
|
+
self.create_with(key: key, enabled: value, klass: klass).find_or_create_by(klass: klass, key: key)
|
47
|
+
value = self.where(key: key, klass: klass).first.enabled
|
48
|
+
define_checker_method(key) { value }
|
49
|
+
define_enabler_method(key) { false }
|
50
|
+
define_disabler_method(key) { false }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def define_checker_method(key, &block)
|
55
|
+
block = Proc.new do
|
56
|
+
record = self.where(key: key, klass: klass).first
|
57
|
+
record.enabled
|
58
|
+
end unless block_given?
|
59
|
+
define_singleton_method("#{key}_enabled?") { block.call }
|
60
|
+
end
|
61
|
+
|
62
|
+
def define_enabler_method(key, &block)
|
63
|
+
block = Proc.new do
|
64
|
+
enable!(key)
|
65
|
+
end unless block_given?
|
66
|
+
define_singleton_method("enable_#{key}!") { block.call }
|
67
|
+
end
|
68
|
+
|
69
|
+
def define_disabler_method(key, &block)
|
70
|
+
block = Proc.new do
|
71
|
+
disable!(key)
|
72
|
+
end unless block_given?
|
73
|
+
define_singleton_method("disable_#{key}!") { block.call }
|
49
74
|
end
|
50
75
|
|
51
76
|
def remove_old_features!
|
@@ -60,14 +85,14 @@ module FeatureSetting
|
|
60
85
|
def enable!(key)
|
61
86
|
if features.key?(key.to_sym)
|
62
87
|
record = self.where(key: key, klass: klass).first
|
63
|
-
record.
|
88
|
+
record.update(enabled: true)
|
64
89
|
end
|
65
90
|
end
|
66
91
|
|
67
92
|
def disable!(key)
|
68
93
|
if features.key?(key.to_sym)
|
69
94
|
record = self.where(key: key, klass: klass).first
|
70
|
-
record.
|
95
|
+
record.update(enabled: false)
|
71
96
|
end
|
72
97
|
end
|
73
98
|
|
@@ -4,8 +4,8 @@ require 'json'
|
|
4
4
|
module FeatureSetting
|
5
5
|
class FsSetting < ActiveRecord::Base
|
6
6
|
SETTINGS = {
|
7
|
-
test: 'value'
|
8
|
-
}
|
7
|
+
test: 'value'
|
8
|
+
}.freeze
|
9
9
|
|
10
10
|
def settings
|
11
11
|
self.class::SETTINGS
|
@@ -17,56 +17,77 @@ module FeatureSetting
|
|
17
17
|
|
18
18
|
class << self
|
19
19
|
def settings
|
20
|
-
|
20
|
+
new.settings
|
21
21
|
end
|
22
22
|
|
23
23
|
def klass
|
24
|
-
|
24
|
+
new.klass.to_s
|
25
25
|
end
|
26
26
|
|
27
|
-
def init_settings!
|
27
|
+
def init_settings!(remove_old_settings = false)
|
28
28
|
settings.each do |key, value|
|
29
|
-
|
29
|
+
create_with(key: key, value: convert_to_string(value, value.class.to_s), value_type: value.class.to_s, klass: klass).find_or_create_by(klass: klass, key: key)
|
30
30
|
define_getter_method(key)
|
31
31
|
define_setter_method(key)
|
32
32
|
end
|
33
|
-
remove_old_settings!
|
33
|
+
remove_old_settings! if remove_old_settings
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
def cache_settings!
|
37
|
+
settings.each do |key, value|
|
38
|
+
create_with(key: key, value: convert_to_string(value, value.class.to_s), value_type: value.class.to_s, klass: klass).find_or_create_by(klass: klass, key: key)
|
39
|
+
record = where(key: key, klass: klass).first
|
40
|
+
value = convert_to_type(record.value, record.value_type)
|
41
|
+
define_getter_method(key) { value }
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
45
|
+
def define_getter_method(key, &block)
|
46
|
+
block = Proc.new do
|
47
|
+
record = where(key: key, klass: klass).first
|
48
|
+
convert_to_type(record.value, record.value_type)
|
49
|
+
end unless block_given?
|
50
|
+
|
51
|
+
define_singleton_method(key.to_s) { block.call }
|
52
|
+
end
|
53
|
+
|
43
54
|
def define_setter_method(key)
|
44
55
|
define_singleton_method("#{key}=") do |value|
|
45
|
-
record = self.where(key: key, klass: klass).first
|
46
56
|
set!(key, value)
|
47
57
|
end
|
48
58
|
end
|
49
59
|
|
50
60
|
def remove_old_settings!
|
51
|
-
|
61
|
+
where(klass: klass, key: all_stored_keys - defined_keys).destroy_all
|
52
62
|
end
|
53
63
|
|
54
64
|
def reset_settings!
|
55
|
-
|
65
|
+
where(klass: klass).destroy_all
|
56
66
|
init_settings!
|
57
67
|
end
|
58
68
|
|
59
|
-
def set!(key = nil, value = nil
|
60
|
-
key
|
61
|
-
|
69
|
+
def set!(key = nil, value = nil)
|
70
|
+
raise 'ERROR: FsSetting key is missing or does not exist.' unless defined_keys.include?(key.to_s)
|
71
|
+
|
72
|
+
record = where(key: key.to_s, klass: klass).first
|
73
|
+
old_value = convert_to_type(record.value, record.value_type)
|
74
|
+
|
75
|
+
if record.value_type == 'Hash'
|
76
|
+
raise 'ERROR: The value for a setting of type Hash must be a Hash.' unless value.is_a?(Hash)
|
62
77
|
|
63
|
-
|
64
|
-
|
65
|
-
|
78
|
+
new_value = old_value.update(value)
|
79
|
+
value_type = 'Hash'
|
80
|
+
else
|
81
|
+
new_value = value
|
82
|
+
value_type = value.class.to_s
|
83
|
+
end
|
84
|
+
|
85
|
+
record.update(
|
66
86
|
value: convert_to_string(new_value, new_value.class.to_s),
|
67
|
-
value_type:
|
87
|
+
value_type: value_type
|
68
88
|
)
|
69
89
|
end
|
90
|
+
alias_method :update!, :set!
|
70
91
|
|
71
92
|
def existing_key(key = nil, hash = {})
|
72
93
|
settings.key?(hash.keys.first) || settings.key?(key.to_sym)
|
@@ -75,14 +96,23 @@ module FeatureSetting
|
|
75
96
|
nil
|
76
97
|
end
|
77
98
|
|
78
|
-
def
|
99
|
+
def defined_keys
|
79
100
|
settings.keys.map(&:to_s)
|
80
101
|
end
|
81
102
|
|
103
|
+
def stored_settings
|
104
|
+
hash = {}
|
105
|
+
where(klass: klass).each do |record|
|
106
|
+
hash[record.key.to_sym] = convert_to_type(record.value, record.value_type)
|
107
|
+
end
|
108
|
+
|
109
|
+
hash
|
110
|
+
end
|
111
|
+
|
82
112
|
private
|
83
113
|
|
84
|
-
def
|
85
|
-
|
114
|
+
def all_stored_keys
|
115
|
+
all.pluck(:key)
|
86
116
|
end
|
87
117
|
|
88
118
|
def convert_to_type(value, type)
|
@@ -97,6 +127,8 @@ module FeatureSetting
|
|
97
127
|
false
|
98
128
|
when 'Fixnum'
|
99
129
|
value.to_i
|
130
|
+
when 'Integer'
|
131
|
+
value.to_i
|
100
132
|
when 'Float'
|
101
133
|
value.to_f
|
102
134
|
when 'Symbol'
|
@@ -110,12 +142,10 @@ module FeatureSetting
|
|
110
142
|
|
111
143
|
def convert_to_string(value, type)
|
112
144
|
case type
|
113
|
-
when 'Hash'
|
145
|
+
when 'Hash', 'Hashie::Mash'
|
114
146
|
value.to_json
|
115
147
|
when 'Array'
|
116
148
|
value.join('|||')
|
117
|
-
when 'Hash'
|
118
|
-
value.to_json
|
119
149
|
else
|
120
150
|
value.to_s
|
121
151
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class CreateFsTables < ActiveRecord::Migration
|
1
|
+
class CreateFsTables < ActiveRecord::Migration[4.2]
|
2
2
|
def self.up
|
3
3
|
create_table :fs_features do |t|
|
4
4
|
t.string :key
|
@@ -15,4 +15,9 @@ class CreateFsTables < ActiveRecord::Migration
|
|
15
15
|
t.timestamps null: false
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
def self.down
|
20
|
+
drop_table :fs_features
|
21
|
+
drop_table :fs_settings
|
22
|
+
end
|
18
23
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: feature_setting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Indro De
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -123,7 +123,7 @@ dependencies:
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: simplecov
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - ">="
|
@@ -166,7 +166,7 @@ homepage: https://github.com/indrode/feature_setting
|
|
166
166
|
licenses:
|
167
167
|
- MIT
|
168
168
|
metadata: {}
|
169
|
-
post_install_message:
|
169
|
+
post_install_message:
|
170
170
|
rdoc_options: []
|
171
171
|
require_paths:
|
172
172
|
- lib
|
@@ -181,9 +181,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
181
|
- !ruby/object:Gem::Version
|
182
182
|
version: '0'
|
183
183
|
requirements: []
|
184
|
-
|
185
|
-
|
186
|
-
signing_key:
|
184
|
+
rubygems_version: 3.0.3
|
185
|
+
signing_key:
|
187
186
|
specification_version: 4
|
188
187
|
summary: A lightweight feature/setting DSL for Rails applications.
|
189
188
|
test_files: []
|