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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ab8e41a32042cf67cc57b481b65f0b91b3b40120
4
- data.tar.gz: 43fe930139c71bf372959fab6a9dff0e87f01ead
2
+ SHA256:
3
+ metadata.gz: 53ffa8db4e5e12eab93ef6a84df1d16c297459643d84139b3f34bf15eed7f88a
4
+ data.tar.gz: 9f88e1e4672bc51d4d1a739e510ffbc448448422870a2b14873318fe49710c44
5
5
  SHA512:
6
- metadata.gz: 6b8a06dc361a89c9f21e5b5903b8bf9975138c7e98c5301ccadba9c5d6048b53e2bf41cb53132212f9cf2f3856c9fc1e01031c3813bb15b7c6c6740b39a50c88
7
- data.tar.gz: 507ebb28119c420308cdfdc562ca0805510335c2c6b148d63d78741f11f54238d320002af36b66c096d602bae95d6841e1a498882142c4691496876e0af84eaa
6
+ metadata.gz: fbe6488bc9eb17cfb6812ce5be36b7d58368436938be2e18ef5105695412a2d4786852befedec892f4b72137a227a4166957bad89a0bedc4de6d8836c3f24f4e
7
+ data.tar.gz: 2753e2457b391937abd777ff998a574cf765052d7de782e52eba986b3d5b33c9561186aaf46fc0fe5070223afc9d02684d41e5401873f16e72ecbda13f4783df
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ .byebug_history
@@ -1,3 +1,12 @@
1
+ env:
2
+ global:
3
+ - CC_TEST_REPORTER_ID=3cb479d83eec93856a43161ba46dbad5b8d2e4979a36754bfc07202277b7f1c6
1
4
  language: ruby
2
- rvm:
3
- - 2.2.2
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 Version](https://badge.fury.io/rb/feature_setting.svg)](http://badge.fury.io/rb/feature_setting) [![Code Climate](https://codeclimate.com/github/indrode/feature_setting/badges/gpa.svg)](https://codeclimate.com/github/indrode/feature_setting) [![Test Coverage](https://codeclimate.com/github/indrode/feature_setting/badges/coverage.svg)](https://codeclimate.com/github/indrode/feature_setting/coverage) [![security](https://hakiri.io/github/indrode/feature_setting/master.svg)](https://hakiri.io/github/indrode/feature_setting/master)
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
- # other ways to set setting values:
114
- Settings.set!(setting_one: 1000)
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
 
@@ -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', '>= 0'
28
- spec.add_development_dependency 'codeclimate-test-reporter', '>= 0'
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
- define_singleton_method("#{key}_enabled?") do
38
- record = self.where(key: key, klass: klass).first
39
- record.enabled
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.update_attributes(enabled: true)
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.update_attributes(enabled: false)
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
- self.new.settings
20
+ new.settings
21
21
  end
22
22
 
23
23
  def klass
24
- self.new.klass.to_s
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
- self.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)
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 define_getter_method(key)
37
- define_singleton_method(key.to_s) do
38
- record = self.where(key: key, klass: klass).first
39
- convert_to_type(record.value, record.value_type)
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
- self.where(klass: klass, key: all_stored_settings - defined_settings).destroy_all
61
+ where(klass: klass, key: all_stored_keys - defined_keys).destroy_all
52
62
  end
53
63
 
54
64
  def reset_settings!
55
- self.where(klass: klass).destroy_all
65
+ where(klass: klass).destroy_all
56
66
  init_settings!
57
67
  end
58
68
 
59
- def set!(key = nil, value = nil, **hash)
60
- key = existing_key(key, hash)
61
- fail 'ERROR: FsSetting key is missing or does not exist.' unless key
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
- record = self.where(key: key, klass: klass).first
64
- new_value = hash.values.first || value
65
- record.update_attributes(
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: new_value.class.to_s
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 defined_settings
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 all_stored_settings
85
- self.all.pluck(:key)
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,3 +1,3 @@
1
1
  module FeatureSetting
2
- VERSION = "1.5.2"
2
+ VERSION = "1.6.2"
3
3
  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.5.2
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: 2016-06-10 00:00:00.000000000 Z
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: codeclimate-test-reporter
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
- rubyforge_project:
185
- rubygems_version: 2.4.5
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: []