settingson 1.6.0 → 1.6.1
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/.codeclimate.yml +33 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +3 -0
- data/Gemfile +2 -0
- data/README.md +6 -13
- data/app/models/concerns/settingson/base.rb +14 -105
- data/gemfiles/4.2.gemfile +1 -0
- data/gemfiles/4.2.gemfile.lock +10 -1
- data/gemfiles/5.0.gemfile +1 -0
- data/gemfiles/5.0.gemfile.lock +11 -1
- data/lib/settingson/store.rb +105 -1
- data/lib/settingson/version.rb +1 -1
- data/spec/dummy/config/initializers/settingson.rb +1 -0
- data/spec/models/settings_spec.rb +39 -9
- data/spec/spec_helper.rb +3 -0
- metadata +6 -2
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[](http://badge.fury.io/rb/settingson)
|
2
2
|
[](https://travis-ci.org/daanforever/settingson)
|
3
3
|
[](https://codeclimate.com/github/daanforever/settingson)
|
4
|
+
[](https://codeclimate.com/github/daanforever/settingson/coverage)
|
4
5
|
|
5
6
|
# Settingson
|
6
7
|
|
@@ -111,23 +112,15 @@ end
|
|
111
112
|
New way:
|
112
113
|
in config/initializers/settingson.rb
|
113
114
|
```ruby
|
114
|
-
Settings.defaults do
|
115
|
-
|
116
|
-
|
115
|
+
Settings.defaults do |conf|
|
116
|
+
conf.server.smtp.host = 'host'
|
117
|
+
conf.server.smtp.port = 25
|
117
118
|
end
|
118
119
|
```
|
119
120
|
|
120
|
-
Old way:
|
121
|
-
in config/initializers/settingson.rb
|
122
121
|
```ruby
|
123
|
-
|
124
|
-
|
125
|
-
Settings.server.smtp.host? || Settings.server.smtp.host = 'host'
|
126
|
-
Settings.server.smtp.port? || Settings.server.smtp.port = '25'
|
127
|
-
rescue
|
128
|
-
Rails.logger.warn('Something goes wrong')
|
129
|
-
end
|
130
|
-
end
|
122
|
+
conf.server.smtp.host # => 'host'
|
123
|
+
conf.server.smtp.port # => 25
|
131
124
|
```
|
132
125
|
|
133
126
|
## Contributing
|
@@ -11,9 +11,8 @@ module Settingson::Base
|
|
11
11
|
#
|
12
12
|
# # or
|
13
13
|
#
|
14
|
-
# Settings.configure.expires = 600
|
15
|
-
# Settings.configure.enabled = true
|
16
|
-
|
14
|
+
# Settings.configure.cache.expires = 600
|
15
|
+
# Settings.configure.cache.enabled = true
|
17
16
|
def configure
|
18
17
|
@_settings ||= ::Settingson::Config.new
|
19
18
|
yield @_settings if block_given?
|
@@ -24,32 +23,15 @@ module Settingson::Base
|
|
24
23
|
# settings.server.host = 'host'
|
25
24
|
# settings.server.port = 80
|
26
25
|
# end
|
27
|
-
# FIXME: not ready yet
|
28
26
|
def defaults
|
27
|
+
return unless block_given?
|
29
28
|
Rails.application.config.after_initialize do
|
30
|
-
|
31
|
-
yield new(settingson: 'defaults') if block_given?
|
32
|
-
rescue
|
33
|
-
Rails.logger.warn('Settingson::defaults failed')
|
34
|
-
end
|
29
|
+
yield Settingson::Store.new( klass: self, path: '__defaults' )
|
35
30
|
end
|
36
|
-
true
|
37
|
-
end
|
38
|
-
|
39
|
-
# Settings.delete_all
|
40
|
-
# Delete cached items before super
|
41
|
-
def delete_all
|
42
|
-
Rails.cache.delete_matched(/#{self.configure.cache.namespace}/)
|
43
|
-
super
|
44
31
|
end
|
45
32
|
|
46
33
|
# Settings.from_hash('smtp.host' => 'host')
|
47
|
-
|
48
|
-
def cached(*args)
|
49
|
-
ActiveSupport::Deprecation.warn('Now caching is enabled by default')
|
50
|
-
self.new
|
51
|
-
end
|
52
|
-
|
34
|
+
# Settings.smtp.host
|
53
35
|
def from_hash(attributes)
|
54
36
|
case attributes
|
55
37
|
when Hash
|
@@ -61,102 +43,29 @@ module Settingson::Base
|
|
61
43
|
end
|
62
44
|
end
|
63
45
|
|
64
|
-
|
46
|
+
# Custom hook for clear cache before delete_all
|
47
|
+
#
|
48
|
+
def delete_all
|
65
49
|
super
|
66
|
-
|
67
|
-
self.new.send(symbol, *args)
|
68
|
-
rescue NoMethodError
|
69
|
-
self.new.send(symbol, *args)
|
50
|
+
Rails.cache.delete_matched(/#{self.configure.cache.namespace}/)
|
70
51
|
end
|
71
52
|
|
53
|
+
def method_missing(symbol, *args)
|
54
|
+
super
|
55
|
+
rescue NameError, NoMethodError
|
56
|
+
Settingson::Store.new(klass: self).send(symbol, args.first)
|
57
|
+
end
|
72
58
|
|
73
59
|
end # module ClassMethods
|
74
60
|
|
75
61
|
included do
|
76
|
-
attr_accessor :settingson
|
77
62
|
serialize :value
|
78
63
|
before_destroy :__delete_cached
|
79
64
|
end
|
80
65
|
|
81
|
-
def __debug(message)
|
82
|
-
Rails.logger.debug(message) if self.class.configure.debug
|
83
|
-
end
|
84
|
-
|
85
66
|
def __delete_cached
|
86
67
|
cache_key = "#{self.class.configure.cache.namespace}/#{self.key}"
|
87
68
|
Rails.cache.delete(cache_key)
|
88
|
-
__debug("#{self.class.name}: delete '#{self.key}' '#{cache_key}'")
|
89
|
-
end
|
90
|
-
|
91
|
-
def to_s
|
92
|
-
self.new_record? ? '' : super
|
93
|
-
end
|
94
|
-
|
95
|
-
def inspect
|
96
|
-
self.new_record? ? '""' : super
|
97
|
-
end
|
98
|
-
|
99
|
-
def to_i
|
100
|
-
self.new_record? ? 0 : super
|
101
|
-
end
|
102
|
-
|
103
|
-
def nil?
|
104
|
-
self.new_record? ? true : super
|
105
|
-
end
|
106
|
-
|
107
|
-
alias empty? nil?
|
108
|
-
|
109
|
-
def method_missing(symbol, *args)
|
110
|
-
super
|
111
|
-
rescue NameError
|
112
|
-
__rescue_action(symbol.to_s, args.first)
|
113
|
-
rescue NoMethodError
|
114
|
-
__rescue_action(symbol.to_s, args.first)
|
115
|
-
end # method_missing
|
116
|
-
|
117
|
-
protected
|
118
|
-
|
119
|
-
def __cached_key
|
120
|
-
[ self.class.configure.cache.namespace, @settingson ].join('/')
|
121
|
-
end
|
122
|
-
|
123
|
-
def __rescue_action(key, value)
|
124
|
-
case key
|
125
|
-
when /(.+)=/ # setter
|
126
|
-
@settingson = [@settingson, $1].compact.join('.')
|
127
|
-
record = self.class.find_or_create_by!(key: @settingson)
|
128
|
-
record.update!(value: value)
|
129
|
-
Rails.cache.write(__cached_key, value)
|
130
|
-
__debug("#{self.class.name}##{__method__} setter '#{__cached_key}'")
|
131
|
-
record.value
|
132
|
-
else # returns values or self
|
133
|
-
@settingson = [@settingson, key].compact.join('.')
|
134
|
-
__debug("#{self.class.name}##{__method__} getter '#{@settingson}'")
|
135
|
-
__cached_value_or_self
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def __cached_value_or_self
|
140
|
-
result = __cached_value
|
141
|
-
result.is_a?(ActiveRecord::RecordNotFound) ? self : result
|
142
|
-
end
|
143
|
-
|
144
|
-
def __cached_value
|
145
|
-
__debug("#{self.class.name}##{__method__} '#{@settingson}'")
|
146
|
-
Rails.cache.fetch(
|
147
|
-
__cached_key,
|
148
|
-
expires_in: self.class.configure.cache.expires,
|
149
|
-
race_condition_ttl: self.class.configure.cache.race_condition_ttl
|
150
|
-
) do
|
151
|
-
__debug("#{self.class.name}: fresh '#{@settingson}'")
|
152
|
-
__fresh_value
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def __fresh_value
|
157
|
-
self.class.find_by!(key: @settingson).value
|
158
|
-
rescue ActiveRecord::RecordNotFound
|
159
|
-
ActiveRecord::RecordNotFound.new
|
160
69
|
end
|
161
70
|
|
162
71
|
end # Settingson::Base
|
data/gemfiles/4.2.gemfile
CHANGED
data/gemfiles/4.2.gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../
|
3
3
|
specs:
|
4
|
-
settingson (1.
|
4
|
+
settingson (1.6.0)
|
5
5
|
rails (>= 4.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -48,9 +48,12 @@ GEM
|
|
48
48
|
thor (>= 0.14.0)
|
49
49
|
arel (6.0.3)
|
50
50
|
builder (3.2.2)
|
51
|
+
codeclimate-test-reporter (0.6.0)
|
52
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
51
53
|
concurrent-ruby (1.0.2)
|
52
54
|
database_cleaner (1.5.3)
|
53
55
|
diff-lcs (1.2.5)
|
56
|
+
docile (1.1.5)
|
54
57
|
erubis (2.7.0)
|
55
58
|
faker (1.6.6)
|
56
59
|
i18n (~> 0.5)
|
@@ -122,6 +125,11 @@ GEM
|
|
122
125
|
rspec-mocks (~> 3.5.0)
|
123
126
|
rspec-support (~> 3.5.0)
|
124
127
|
rspec-support (3.5.0)
|
128
|
+
simplecov (0.12.0)
|
129
|
+
docile (~> 1.1.0)
|
130
|
+
json (>= 1.8, < 3)
|
131
|
+
simplecov-html (~> 0.10.0)
|
132
|
+
simplecov-html (0.10.0)
|
125
133
|
spring (1.7.2)
|
126
134
|
spring-commands-rspec (1.0.4)
|
127
135
|
spring (>= 0.9.1)
|
@@ -144,6 +152,7 @@ PLATFORMS
|
|
144
152
|
DEPENDENCIES
|
145
153
|
appraisal
|
146
154
|
bundler (>= 1.6)
|
155
|
+
codeclimate-test-reporter
|
147
156
|
database_cleaner
|
148
157
|
faker
|
149
158
|
rails (~> 4.2.0)
|
data/gemfiles/5.0.gemfile
CHANGED
data/gemfiles/5.0.gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../
|
3
3
|
specs:
|
4
|
-
settingson (1.
|
4
|
+
settingson (1.6.0)
|
5
5
|
rails (>= 4.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -50,15 +50,19 @@ GEM
|
|
50
50
|
thor (>= 0.14.0)
|
51
51
|
arel (7.1.2)
|
52
52
|
builder (3.2.2)
|
53
|
+
codeclimate-test-reporter (0.6.0)
|
54
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
53
55
|
concurrent-ruby (1.0.2)
|
54
56
|
database_cleaner (1.5.3)
|
55
57
|
diff-lcs (1.2.5)
|
58
|
+
docile (1.1.5)
|
56
59
|
erubis (2.7.0)
|
57
60
|
faker (1.6.6)
|
58
61
|
i18n (~> 0.5)
|
59
62
|
globalid (0.3.7)
|
60
63
|
activesupport (>= 4.1.0)
|
61
64
|
i18n (0.7.0)
|
65
|
+
json (2.0.2)
|
62
66
|
loofah (2.0.3)
|
63
67
|
nokogiri (>= 1.5.9)
|
64
68
|
mail (2.6.4)
|
@@ -124,6 +128,11 @@ GEM
|
|
124
128
|
rspec-mocks (~> 3.5.0)
|
125
129
|
rspec-support (~> 3.5.0)
|
126
130
|
rspec-support (3.5.0)
|
131
|
+
simplecov (0.12.0)
|
132
|
+
docile (~> 1.1.0)
|
133
|
+
json (>= 1.8, < 3)
|
134
|
+
simplecov-html (~> 0.10.0)
|
135
|
+
simplecov-html (0.10.0)
|
127
136
|
spring (1.7.2)
|
128
137
|
spring-commands-rspec (1.0.4)
|
129
138
|
spring (>= 0.9.1)
|
@@ -149,6 +158,7 @@ PLATFORMS
|
|
149
158
|
DEPENDENCIES
|
150
159
|
appraisal
|
151
160
|
bundler (>= 1.6)
|
161
|
+
codeclimate-test-reporter
|
152
162
|
database_cleaner
|
153
163
|
faker
|
154
164
|
rails (~> 5.0.0)
|
data/lib/settingson/store.rb
CHANGED
@@ -1,4 +1,108 @@
|
|
1
|
-
|
1
|
+
class Settingson::Store
|
2
2
|
|
3
|
+
def initialize(klass:, path: nil)
|
4
|
+
@__klass = klass
|
5
|
+
@__path = path
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
self.new_record? ? '' : super
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_i
|
13
|
+
self.new_record? ? 0 : super
|
14
|
+
end
|
15
|
+
|
16
|
+
def nil?
|
17
|
+
self.new_record? ? true : super
|
18
|
+
end
|
19
|
+
|
20
|
+
alias empty? nil?
|
21
|
+
|
22
|
+
def method_missing(symbol, *args)
|
23
|
+
__rescue_action(symbol.to_s, args.first)
|
24
|
+
end # method_missing
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def __debug(message)
|
29
|
+
message = sprintf("%s#%-32s: %s",
|
30
|
+
self.class.name,
|
31
|
+
caller_locations.first.label,
|
32
|
+
message)
|
33
|
+
Rails.logger.debug(message) if @__klass.configure.debug
|
34
|
+
end
|
35
|
+
|
36
|
+
def __rescue_action(key, value)
|
37
|
+
case key
|
38
|
+
when /(.+)=/ # setter
|
39
|
+
__debug("set '#{$1}' value '#{value}' path '#{@__path}'")
|
40
|
+
__set($1, value)
|
41
|
+
else # returns values or self
|
42
|
+
__debug("get '#{key}' value '#{value}' path '#{@__path}'")
|
43
|
+
__get(key)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def __set(key, value)
|
48
|
+
__update_search_path(key)
|
49
|
+
if record = @__klass.find_by(key: @__path)
|
50
|
+
record.update!(value: value)
|
51
|
+
else
|
52
|
+
@__klass.create!(key: @__path, value: value)
|
53
|
+
end
|
54
|
+
Rails.cache.write(__cache_key(@__path), value)
|
55
|
+
value
|
56
|
+
end
|
57
|
+
|
58
|
+
def __get(key)
|
59
|
+
__update_search_path(key)
|
60
|
+
result = __cached_or_default_value(@__path)
|
61
|
+
|
62
|
+
if result.is_a?(ActiveRecord::RecordNotFound)
|
63
|
+
__debug("return self with path: #{@__path}")
|
64
|
+
self
|
65
|
+
else
|
66
|
+
__debug("return result")
|
67
|
+
result
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def __update_search_path(key)
|
72
|
+
@__path = [@__path, key].compact.join('.')
|
73
|
+
end
|
74
|
+
|
75
|
+
def __cached_or_default_value(key)
|
76
|
+
result = __cached_value(key)
|
77
|
+
|
78
|
+
if result.is_a?(ActiveRecord::RecordNotFound) # Try defaults
|
79
|
+
__cached_value('__defaults.' + key)
|
80
|
+
else
|
81
|
+
result
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def __cache_key(key)
|
86
|
+
[ @__klass.configure.cache.namespace, key ].join('/')
|
87
|
+
end
|
88
|
+
|
89
|
+
def __cached_value(key)
|
90
|
+
__debug("looking in cache '#{__cache_key(key)}'")
|
91
|
+
Rails.cache.fetch(
|
92
|
+
__cache_key(key),
|
93
|
+
expires_in: @__klass.configure.cache.expires,
|
94
|
+
race_condition_ttl: @__klass.configure.cache.race_condition_ttl
|
95
|
+
) do
|
96
|
+
__debug("ask DB '#{key}'")
|
97
|
+
__get_from_db(key)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def __get_from_db(key)
|
102
|
+
@__klass.find_by!(key: key).value
|
103
|
+
rescue ActiveRecord::RecordNotFound
|
104
|
+
__debug("not found")
|
105
|
+
ActiveRecord::RecordNotFound.new
|
106
|
+
end
|
3
107
|
|
4
108
|
end
|
data/lib/settingson/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
Settings.configure.debug = true
|
@@ -2,9 +2,32 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Settings do
|
4
4
|
|
5
|
-
describe '
|
6
|
-
it 'not raises errors' do
|
7
|
-
expect{ Settings.
|
5
|
+
describe '::defaults' do
|
6
|
+
it 'not raises errors without parameters' do
|
7
|
+
expect{ Settings.defaults {} }.to_not raise_error
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns default value for simple value' do
|
11
|
+
word = Faker::Lorem.word
|
12
|
+
Settings.defaults{|s| s.cached_key = word}
|
13
|
+
expect( Settings.cached_key ).to eq(word)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'returns default value for complex value' do
|
17
|
+
word = Faker::Lorem.word
|
18
|
+
Settings.defaults{|s| s.some.key = word}
|
19
|
+
expect( Settings.some.key ).to eq(word)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '::from_hash' do
|
24
|
+
it 'accessable by hash key' do
|
25
|
+
Settings.from_hash(hello: :world)
|
26
|
+
expect( Settings.hello ).to eq(:world)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'raises error when not Hash' do
|
30
|
+
expect{Settings.from_hash([:hello, :world])}.to raise_error(ArgumentError)
|
8
31
|
end
|
9
32
|
end
|
10
33
|
|
@@ -15,11 +38,13 @@ describe Settings do
|
|
15
38
|
it 'not raises error on create new element' do
|
16
39
|
expect{ Settings.hello = Faker::Lorem.word }.to_not raise_error
|
17
40
|
end
|
18
|
-
it 'returns same Fixnum' do
|
19
|
-
word = Faker::Lorem.word
|
41
|
+
it 'returns same Fixnum #1' do
|
20
42
|
Settings.number = 100
|
21
43
|
expect( Settings.number ).to eq(100)
|
22
44
|
end
|
45
|
+
it 'returns 0 when key not found' do
|
46
|
+
expect( Settings.not_found.to_i ).to eq(0)
|
47
|
+
end
|
23
48
|
it 'returns same String' do
|
24
49
|
word = Faker::Lorem.word
|
25
50
|
Settings.hello = word
|
@@ -27,13 +52,18 @@ describe Settings do
|
|
27
52
|
end
|
28
53
|
it 'returns same value for complex key #1' do
|
29
54
|
word = Faker::Lorem.word
|
30
|
-
Settings.
|
31
|
-
expect( Settings.
|
55
|
+
Settings.hello1.hello2 = word
|
56
|
+
expect( Settings.hello1.hello2 ).to eq(word)
|
32
57
|
end
|
33
58
|
it 'returns same value for complex key #2' do
|
34
59
|
word = Faker::Lorem.word
|
35
|
-
Settings.
|
36
|
-
expect( Settings.
|
60
|
+
Settings.hello.key = word
|
61
|
+
expect( Settings.hello.key ).to eq(word)
|
62
|
+
end
|
63
|
+
it 'returns same value for complex key #3' do
|
64
|
+
word = Faker::Lorem.word
|
65
|
+
Settings.hello.hello = word
|
66
|
+
expect( Settings.hello.hello ).to eq(word)
|
37
67
|
end
|
38
68
|
it 'not destroys record with nil value #1' do
|
39
69
|
word = Faker::Lorem.word
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: settingson
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- dan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -157,8 +157,10 @@ executables: []
|
|
157
157
|
extensions: []
|
158
158
|
extra_rdoc_files: []
|
159
159
|
files:
|
160
|
+
- ".codeclimate.yml"
|
160
161
|
- ".gitignore"
|
161
162
|
- ".rspec"
|
163
|
+
- ".rubocop.yml"
|
162
164
|
- ".travis.yml"
|
163
165
|
- Appraisals
|
164
166
|
- Gemfile
|
@@ -212,6 +214,7 @@ files:
|
|
212
214
|
- spec/dummy/config/initializers/inflections.rb
|
213
215
|
- spec/dummy/config/initializers/mime_types.rb
|
214
216
|
- spec/dummy/config/initializers/session_store.rb
|
217
|
+
- spec/dummy/config/initializers/settingson.rb
|
215
218
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
216
219
|
- spec/dummy/config/locales/en.yml
|
217
220
|
- spec/dummy/config/routes.rb
|
@@ -286,6 +289,7 @@ test_files:
|
|
286
289
|
- spec/dummy/config/initializers/inflections.rb
|
287
290
|
- spec/dummy/config/initializers/mime_types.rb
|
288
291
|
- spec/dummy/config/initializers/session_store.rb
|
292
|
+
- spec/dummy/config/initializers/settingson.rb
|
289
293
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
290
294
|
- spec/dummy/config/locales/en.yml
|
291
295
|
- spec/dummy/config/routes.rb
|