rails-settings-cached 2.0.2 → 2.2.0
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/MIT-LICENSE +1 -2
- data/README.md +90 -21
- data/lib/generators/settings/install_generator.rb +7 -3
- data/lib/rails-settings/base.rb +33 -20
- data/lib/rails-settings/version.rb +1 -1
- metadata +22 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 765057576ddcdb19d9f394f1844950f03e8c70944abd9b104e70824f60f7e0e5
|
4
|
+
data.tar.gz: 0d2a2c4aa7560d96bee3a0c1a0d50f7cb89bffd5c650ae47f2bd6169c0d12b6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 908f7ae3d8e01710f9df4cb32a77b2302129107bcd34254cb5237fc5f5b98f2e4007fe315751ab3fd7e2212e14a0db133f796f994b0bd6a1cee48768717a01a9
|
7
|
+
data.tar.gz: fe611e7af4ac5ca72a98040c63b0475833878ac6f11b82953fd80458bb6b96311fff7fc174f890171f466f724be809cd334bc184b0cb0c8c7b3ae94f5fbee28f
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
## Rails Settings Cached
|
2
2
|
|
3
3
|
This a plugin that makes managing a table of
|
4
|
-
global key, value pairs easy. Think of it like a global Hash stored in your database,
|
4
|
+
а global key, value pairs easy. Think of it like a global Hash stored in your database,
|
5
5
|
that uses simple ActiveRecord like methods for manipulation. Keep track of any global
|
6
|
-
setting that you
|
6
|
+
setting that you don't want to hard code into your rails app. You can store any kind
|
7
7
|
of object. Strings, numbers, arrays, or any object.
|
8
8
|
|
9
9
|
> 🚨 BREAK CHANGES WARNING:
|
10
|
-
> rails-settings-cached 2.x has
|
11
|
-
> When you
|
10
|
+
> rails-settings-cached 2.x has redesigned the API, the new version will compatible with the stored setting values by an older version.
|
11
|
+
> When you want to upgrade 2.x, you must read the README again, and follow guides to change your Setting model.
|
12
|
+
> 0.x stable branch: https://github.com/huacnlee/rails-settings-cached/tree/0.x
|
12
13
|
|
13
14
|
## Status
|
14
15
|
|
@@ -19,7 +20,7 @@ of object. Strings, numbers, arrays, or any object.
|
|
19
20
|
Edit your Gemfile:
|
20
21
|
|
21
22
|
```ruby
|
22
|
-
gem "rails-settings-cached"
|
23
|
+
gem "rails-settings-cached", "~> 2.0"
|
23
24
|
```
|
24
25
|
|
25
26
|
Generate your settings:
|
@@ -49,7 +50,10 @@ class Setting < RailsSettings::Base
|
|
49
50
|
field :host, default: "http://example.com"
|
50
51
|
field :readonly_item, type: :integer, default: 100, readonly: true
|
51
52
|
field :user_limits, type: :integer, default: 20
|
53
|
+
field :exchange_rate, type: :float, default: 0.123
|
52
54
|
field :admin_emails, type: :array, default: %w[admin@rubyonrails.org]
|
55
|
+
# Override array separator, default: /[\n,]/ split with \n or comma.
|
56
|
+
field :tips, type: :array, separator: /[\n]+/
|
53
57
|
field :captcha_enable, type: :boolean, default: 1
|
54
58
|
field :notification_options, type: :hash, default: {
|
55
59
|
send_all: true,
|
@@ -59,7 +63,7 @@ class Setting < RailsSettings::Base
|
|
59
63
|
end
|
60
64
|
```
|
61
65
|
|
62
|
-
You must use `field` method to statement the setting keys,
|
66
|
+
You must use `field` method to statement the setting keys, otherwise you can't use it.
|
63
67
|
|
64
68
|
Now just put that migration in the database with:
|
65
69
|
|
@@ -69,7 +73,7 @@ rake db:migrate
|
|
69
73
|
|
70
74
|
## Usage
|
71
75
|
|
72
|
-
The syntax is easy. First,
|
76
|
+
The syntax is easy. First, let's create some settings to keep track of:
|
73
77
|
|
74
78
|
```ruby
|
75
79
|
irb > Setting.host
|
@@ -132,7 +136,7 @@ irb > Setting.notification_options
|
|
132
136
|
|
133
137
|
## Readonly field
|
134
138
|
|
135
|
-
|
139
|
+
Sometimes you may need to use Setting before Rails is initialized, for example `config/devise.rb`
|
136
140
|
|
137
141
|
```rb
|
138
142
|
Devise.setup do |config|
|
@@ -162,9 +166,9 @@ Setting.host -> Check Cache -> Exist - Get value of key for cache -> Return
|
|
162
166
|
Return default value or nil
|
163
167
|
```
|
164
168
|
|
165
|
-
In each Setting keys call, we will load the cache/db and save in
|
169
|
+
In each Setting keys call, we will load the cache/db and save in [RequestStore](https://github.com/steveklabnik/request_store) to avoid hit cache/db.
|
166
170
|
|
167
|
-
Each key update will
|
171
|
+
Each key update will expire the cache, so do not add some frequent update key.
|
168
172
|
|
169
173
|
## Change cache key
|
170
174
|
|
@@ -189,9 +193,9 @@ end
|
|
189
193
|
|
190
194
|
-----
|
191
195
|
|
192
|
-
## How to manage Settings in admin interface?
|
196
|
+
## How to manage Settings in the admin interface?
|
193
197
|
|
194
|
-
If you want create an admin interface to editing the Settings, you can try methods in
|
198
|
+
If you want to create an admin interface to editing the Settings, you can try methods in following:
|
195
199
|
|
196
200
|
config/routes.rb
|
197
201
|
|
@@ -209,18 +213,13 @@ module Admin
|
|
209
213
|
class SettingsController < ApplicationController
|
210
214
|
before_action :get_setting, only: [:edit, :update]
|
211
215
|
|
212
|
-
def show
|
213
|
-
end
|
214
|
-
|
215
216
|
def create
|
216
217
|
setting_params.keys.each do |key|
|
217
|
-
next if key.to_s == "site_logo"
|
218
218
|
Setting.send("#{key}=", setting_params[key].strip) unless setting_params[key].nil?
|
219
219
|
end
|
220
|
-
redirect_to
|
220
|
+
redirect_to settings_path, notice: "Setting was successfully updated."
|
221
221
|
end
|
222
222
|
|
223
|
-
|
224
223
|
private
|
225
224
|
def setting_params
|
226
225
|
params.require(:setting).permit(:host, :user_limits, :admin_emails,
|
@@ -256,10 +255,80 @@ app/views/admin/settings/show.html.erb
|
|
256
255
|
<%= f.text_area :notification_options, value: YAML.dump(Setting.notification_options), class: "form-control", style: "height: 180px;" %>
|
257
256
|
<div class="form-text">
|
258
257
|
Use YAML format to config the SMTP_html
|
259
|
-
</
|
258
|
+
</div>
|
259
|
+
</div>
|
260
260
|
<% end %>
|
261
261
|
```
|
262
262
|
|
263
|
-
##
|
263
|
+
## Backward compatible to support 0.x scoped settings
|
264
|
+
|
265
|
+
You may used the scoped setting feature in 0.x version. Before you upgrade rails-settings-cached 2.x, you must follow this guide to backward compatible it.
|
266
|
+
|
267
|
+
For example:
|
268
|
+
|
269
|
+
```rb
|
270
|
+
class User < ApplicationRecord
|
271
|
+
include RailsSettings::Extend
|
272
|
+
end
|
273
|
+
|
274
|
+
@user.settings.color = "red"
|
275
|
+
@user.settings.foo = 123
|
276
|
+
```
|
277
|
+
|
278
|
+
create `app/models/concerns/scoped_setting.rb`
|
279
|
+
|
280
|
+
```rb
|
281
|
+
module ScopedSetting
|
282
|
+
extend ActiveSupport::Concern
|
283
|
+
|
284
|
+
included do
|
285
|
+
has_many :settings, as: :thing
|
286
|
+
end
|
287
|
+
|
288
|
+
class_methods do
|
289
|
+
def scoped_field(name, default: nil)
|
290
|
+
define_method(name) do
|
291
|
+
obj = settings.where(var: name).take || settings.new(var: name, value: default)
|
292
|
+
obj.value
|
293
|
+
end
|
294
|
+
|
295
|
+
define_method("#{name}=") do |val|
|
296
|
+
record = settings.where(var: name).take || settings.new(var: name)
|
297
|
+
record.value = val
|
298
|
+
record.save!
|
299
|
+
|
300
|
+
val
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
```
|
306
|
+
|
307
|
+
Now include it for your model:
|
308
|
+
|
309
|
+
```rb
|
310
|
+
class User < ApplicationRecord
|
311
|
+
include ScopedSetting
|
312
|
+
|
313
|
+
scoped_field :color, default: ""
|
314
|
+
scoped_field :foo, default: 0
|
315
|
+
end
|
316
|
+
```
|
317
|
+
|
318
|
+
Now you must to find project with ".setting." for replace with:
|
319
|
+
|
320
|
+
Same values will fetch from the `settings` table.
|
321
|
+
|
322
|
+
```rb
|
323
|
+
@user.color = "red"
|
324
|
+
@user.color # => "red"
|
325
|
+
@user.foo = 123
|
326
|
+
@user.foo # =>
|
327
|
+
```
|
328
|
+
|
329
|
+
## Use cases:
|
264
330
|
|
265
|
-
- [ruby-china/
|
331
|
+
- [ruby-china/homeland](https://github.com/ruby-china/homeland)
|
332
|
+
- [thebluedoc/bluedoc](https://github.com/thebluedoc/bluedoc/blob/master/app/models/setting.rb)
|
333
|
+
- [tootsuite/mastodon](https://github.com/tootsuite/mastodon)
|
334
|
+
- [helpyio/helpy](https://github.com/helpyio/helpy)
|
@@ -32,12 +32,16 @@ module Settings
|
|
32
32
|
migration_template "migration.rb", "db/migrate/create_settings.rb", migration_version: migration_version
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
Rails
|
35
|
+
def rails_version_major
|
36
|
+
Rails::VERSION::MAJOR
|
37
|
+
end
|
38
|
+
|
39
|
+
def rails_version_minor
|
40
|
+
Rails::VERSION::MINOR
|
37
41
|
end
|
38
42
|
|
39
43
|
def migration_version
|
40
|
-
"[#{
|
44
|
+
"[#{rails_version_major}.#{rails_version_minor}]" if rails_version_major >= 5
|
41
45
|
end
|
42
46
|
end
|
43
47
|
end
|
data/lib/rails-settings/base.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "request_store"
|
4
|
+
|
3
5
|
module RailsSettings
|
4
6
|
class Base < ActiveRecord::Base
|
5
7
|
class SettingNotFound < RuntimeError; end
|
6
8
|
|
7
|
-
SEPARATOR_REGEXP = /[\
|
9
|
+
SEPARATOR_REGEXP = /[\n,;]+/
|
8
10
|
self.table_name = table_name_prefix + "settings"
|
9
11
|
|
10
12
|
# get the value field, YAML decoded
|
@@ -23,12 +25,14 @@ module RailsSettings
|
|
23
25
|
|
24
26
|
class << self
|
25
27
|
def clear_cache
|
26
|
-
|
28
|
+
RequestStore.store[:rails_settings_all_settings] = nil
|
27
29
|
Rails.cache.delete(self.cache_key)
|
28
30
|
end
|
29
31
|
|
30
32
|
def field(key, **opts)
|
31
|
-
|
33
|
+
@keys ||= []
|
34
|
+
@keys << key.to_s
|
35
|
+
_define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly], separator: opts[:separator])
|
32
36
|
end
|
33
37
|
|
34
38
|
def cache_prefix(&block)
|
@@ -41,14 +45,19 @@ module RailsSettings
|
|
41
45
|
scope.join("/")
|
42
46
|
end
|
43
47
|
|
48
|
+
def keys
|
49
|
+
@keys
|
50
|
+
end
|
51
|
+
|
44
52
|
private
|
45
|
-
|
53
|
+
|
54
|
+
def _define_field(key, default: nil, type: :string, readonly: false, separator: nil)
|
46
55
|
if readonly
|
47
|
-
|
48
|
-
self.send(:
|
56
|
+
define_singleton_method(key) do
|
57
|
+
self.send(:_convert_string_to_typeof_value, type, default, separator: separator)
|
49
58
|
end
|
50
59
|
else
|
51
|
-
|
60
|
+
define_singleton_method(key) do
|
52
61
|
val = self.send(:_value_of, key)
|
53
62
|
result = nil
|
54
63
|
if !val.nil?
|
@@ -58,16 +67,16 @@ module RailsSettings
|
|
58
67
|
result = default.call if default.is_a?(Proc)
|
59
68
|
end
|
60
69
|
|
61
|
-
result = self.send(:
|
70
|
+
result = self.send(:_convert_string_to_typeof_value, type, result, separator: separator)
|
62
71
|
|
63
72
|
result
|
64
73
|
end
|
65
74
|
|
66
|
-
|
75
|
+
define_singleton_method("#{key}=") do |value|
|
67
76
|
var_name = key.to_s
|
68
77
|
|
69
78
|
record = find_by(var: var_name) || new(var: var_name)
|
70
|
-
value = self.send(:
|
79
|
+
value = self.send(:_convert_string_to_typeof_value, type, value, separator: separator)
|
71
80
|
|
72
81
|
record.value = value
|
73
82
|
record.save!
|
@@ -77,26 +86,30 @@ module RailsSettings
|
|
77
86
|
end
|
78
87
|
|
79
88
|
if type == :boolean
|
80
|
-
|
89
|
+
define_singleton_method("#{key}?") do
|
81
90
|
self.send(key)
|
82
91
|
end
|
83
92
|
end
|
84
93
|
end
|
85
94
|
|
86
|
-
def
|
87
|
-
return value unless
|
95
|
+
def _convert_string_to_typeof_value(type, value, separator: nil)
|
96
|
+
return value unless [String, Integer, Float, BigDecimal].include?(value.class)
|
88
97
|
|
89
98
|
case type
|
90
99
|
when :boolean
|
91
|
-
|
100
|
+
value == "true" || value == "1" || value == 1 || value == true
|
92
101
|
when :array
|
93
|
-
|
102
|
+
value.split(separator || SEPARATOR_REGEXP).reject { |str| str.empty? }.map(&:strip)
|
94
103
|
when :hash
|
95
|
-
value = YAML.load(value).
|
104
|
+
value = YAML.load(value).to_h rescue eval(value).to_h rescue {}
|
96
105
|
value.deep_stringify_keys!
|
97
|
-
|
106
|
+
value
|
98
107
|
when :integer
|
99
|
-
|
108
|
+
value.to_i
|
109
|
+
when :float
|
110
|
+
value.to_f
|
111
|
+
when :big_decimal
|
112
|
+
value.to_d
|
100
113
|
else
|
101
114
|
value
|
102
115
|
end
|
@@ -113,8 +126,8 @@ module RailsSettings
|
|
113
126
|
end
|
114
127
|
|
115
128
|
def _all_settings
|
116
|
-
raise "You
|
117
|
-
|
129
|
+
raise "You cannot use settings before Rails initialize." unless rails_initialized?
|
130
|
+
RequestStore.store[:rails_settings_all_settings] ||= begin
|
118
131
|
Rails.cache.fetch(self.cache_key, expires_in: 1.week) do
|
119
132
|
vars = unscoped.select("var, value")
|
120
133
|
result = {}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-settings-cached
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Lee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -25,7 +25,21 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 4.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: request_store
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: codecov
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - ">="
|
@@ -39,7 +53,7 @@ dependencies:
|
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
56
|
+
name: minitest
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - ">="
|
@@ -53,7 +67,7 @@ dependencies:
|
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
70
|
+
name: rubocop
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - ">="
|
@@ -67,7 +81,7 @@ dependencies:
|
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: simplecov
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
@@ -81,7 +95,7 @@ dependencies:
|
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
98
|
+
name: sqlite3
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - ">="
|
@@ -133,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
147
|
- !ruby/object:Gem::Version
|
134
148
|
version: '0'
|
135
149
|
requirements: []
|
136
|
-
rubygems_version: 3.0.
|
150
|
+
rubygems_version: 3.0.3
|
137
151
|
signing_key:
|
138
152
|
specification_version: 4
|
139
153
|
summary: Settings plugin for Rails that makes managing a table of global keys.
|