rails-settings-cached 2.4.0 → 2.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +89 -12
- data/lib/rails-settings-cached.rb +1 -1
- data/lib/rails-settings/base.rb +33 -25
- data/lib/rails-settings/railtie.rb +1 -1
- data/lib/rails-settings/request_cache.rb +30 -0
- data/lib/rails-settings/version.rb +1 -1
- metadata +15 -15
- data/lib/rails-settings/request_store.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc604a3e9ea5a7ed498250820ca7e93ec44e38adb88380b24b0f7b2d5dc164b8
|
4
|
+
data.tar.gz: 9e62d3f49c59e981655a22924d2c32d346ba4618a6c98b4b8b1a0dfb6fd6db24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7bfc23cb9fadddad15c1f3c341973bae5571cdb324ebb7d71f8c075c3877912d7f40b2792cbeaa582a79f22bcde166def831506c95d90444cd7193077492d4a7
|
7
|
+
data.tar.gz: dc55136872ad58751d08f745d93a7707e3e815f6ffc99adcc5d63b19e980594a7874c11484976b7342932ca511ace408c8d48bdd5de5666854b544d908345678
|
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# Rails Settings Cached
|
2
2
|
|
3
|
-
|
4
|
-
а global key, value pairs easy. Think of it like a global Hash stored in your database,
|
5
|
-
that uses simple ActiveRecord like methods for manipulation. Keep track of any global
|
6
|
-
setting that you don't want to hard code into your rails app. You can store any kind
|
7
|
-
of object. Strings, numbers, arrays, or any object.
|
3
|
+
The best solution for store global settings in Rails applications.
|
8
4
|
|
9
|
-
|
5
|
+
This gem will make managing a table of а global key, value pairs easy. Think of it like a global Hash stored in your database, that uses simple ActiveRecord like methods for manipulation. Keep track of any global setting that you don't want to hard code into your rails app.
|
6
|
+
|
7
|
+
You can store any kind of object. Strings, numbers, arrays, booleans, or any object.
|
8
|
+
|
9
|
+
[![Gem Version](https://badge.fury.io/rb/rails-settings-cached.svg)](https://rubygems.org/gems/rails-settings-cached) [![build](https://github.com/huacnlee/rails-settings-cached/workflows/build/badge.svg)](https://github.com/huacnlee/rails-settings-cached/actions?query=workflow%3Abuild) [![codecov.io](https://codecov.io/github/huacnlee/rails-settings-cached/coverage.svg?branch=master)](https://codecov.io/github/huacnlee/rails-settings-cached?branch=master)
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
@@ -30,9 +30,9 @@ You will get `app/models/setting.rb`
|
|
30
30
|
```rb
|
31
31
|
class Setting < RailsSettings::Base
|
32
32
|
# cache_prefix { "v1" }
|
33
|
-
field :app_name, default: "Rails Settings"
|
33
|
+
field :app_name, default: "Rails Settings", validates: { presence: true, length: { in: 2..20 } }
|
34
34
|
field :host, default: "http://example.com", readonly: true
|
35
|
-
field :default_locale, default: "zh-CN"
|
35
|
+
field :default_locale, default: "zh-CN", validates: { presence: true, inclusion: { in: %w[zh-CN en jp] } }
|
36
36
|
field :readonly_item, type: :integer, default: 100, readonly: true
|
37
37
|
field :user_limits, type: :integer, default: 20
|
38
38
|
field :exchange_rate, type: :float, default: 0.123
|
@@ -49,11 +49,11 @@ class Setting < RailsSettings::Base
|
|
49
49
|
}
|
50
50
|
|
51
51
|
# lambda default value
|
52
|
-
field :welcome_message, type: :string, default: -> { "welcome to #{self.app_name}" }
|
52
|
+
field :welcome_message, type: :string, default: -> { "welcome to #{self.app_name}" }, validates: { length: { maximum: 255 } }
|
53
53
|
end
|
54
54
|
```
|
55
55
|
|
56
|
-
You must use `field` method to statement the setting keys, otherwise you can't use it.
|
56
|
+
You must use the `field` method to statement the setting keys, otherwise you can't use it.
|
57
57
|
|
58
58
|
Now just put that migration in the database with:
|
59
59
|
|
@@ -150,9 +150,56 @@ Setting.get_field("app_name")
|
|
150
150
|
=> { key: "app_name", type: :string, default: "Rails Settings", readonly: false }
|
151
151
|
```
|
152
152
|
|
153
|
+
## Validations
|
154
|
+
|
155
|
+
You can use `validates` options to special the [Rails Validation](https://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates) for fields.
|
156
|
+
|
157
|
+
```rb
|
158
|
+
class Setting < RailsSettings::Base
|
159
|
+
# cache_prefix { "v1" }
|
160
|
+
field :app_name, default: "Rails Settings", validates: { presence: true, length: { in: 2..20 } }
|
161
|
+
field :default_locale, default: "zh-CN", validates: { presence: true, inclusion: { in: %w[zh-CN en jp], message: "is not included in [zh-CN, en, jp]" } }
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
Now validate will work on record save:
|
166
|
+
|
167
|
+
```rb
|
168
|
+
irb> Setting.app_name = ""
|
169
|
+
ActiveRecord::RecordInvalid: (Validation failed: App name can't be blank)
|
170
|
+
irb> Setting.app_name = "Rails Settings"
|
171
|
+
"Rails Settings"
|
172
|
+
irb> Setting.default_locale = "zh-TW"
|
173
|
+
ActiveRecord::RecordInvalid: (Validation failed: Default locale is not included in [zh-CN, en, jp])
|
174
|
+
irb> Setting.default_locale = "en"
|
175
|
+
"en"
|
176
|
+
```
|
177
|
+
|
178
|
+
Validate by `save` / `valid?` method:
|
179
|
+
|
180
|
+
```rb
|
181
|
+
|
182
|
+
setting = Setting.find_or_initialize_by(var: :app_name)
|
183
|
+
setting.value = ""
|
184
|
+
setting.valid?
|
185
|
+
# => false
|
186
|
+
setting.errors.full_messages
|
187
|
+
# => ["App name can't be blank", "App name too short (minimum is 2 characters)"]
|
188
|
+
|
189
|
+
setting = Setting.find_or_initialize_by(var: :default_locale)
|
190
|
+
setting.value = "zh-TW"
|
191
|
+
setting.save
|
192
|
+
# => false
|
193
|
+
setting.errors.full_messages
|
194
|
+
# => ["Default locale is not included in [zh-CN, en, jp]"]
|
195
|
+
setting.value = "en"
|
196
|
+
setting.valid?
|
197
|
+
# => true
|
198
|
+
```
|
199
|
+
|
153
200
|
## Use Setting in Rails initializing:
|
154
201
|
|
155
|
-
In `version 2.3+`
|
202
|
+
In `version 2.3+` you can use Setting before Rails is initialized.
|
156
203
|
|
157
204
|
For example `config/initializers/devise.rb`
|
158
205
|
|
@@ -265,9 +312,25 @@ app/controllers/admin/settings_controller.rb
|
|
265
312
|
module Admin
|
266
313
|
class SettingsController < ApplicationController
|
267
314
|
def create
|
315
|
+
@errors = ActiveModel::Errors.new
|
316
|
+
setting_params.keys.each do |key|
|
317
|
+
next if setting_params[key].nil?
|
318
|
+
|
319
|
+
setting = Setting.new(var: key)
|
320
|
+
setting.value = setting_params[key].strip
|
321
|
+
unless setting.valid?
|
322
|
+
@errors.merge!(setting.errors)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
if @errors.any?
|
327
|
+
render :new
|
328
|
+
end
|
329
|
+
|
268
330
|
setting_params.keys.each do |key|
|
269
331
|
Setting.send("#{key}=", setting_params[key].strip) unless setting_params[key].nil?
|
270
332
|
end
|
333
|
+
|
271
334
|
redirect_to admin_settings_path, notice: "Setting was successfully updated."
|
272
335
|
end
|
273
336
|
|
@@ -284,6 +347,16 @@ app/views/admin/settings/show.html.erb
|
|
284
347
|
|
285
348
|
```erb
|
286
349
|
<%= form_for(Setting.new, url: admin_settings_path) do |f| %>
|
350
|
+
<% if @errors.any? %>
|
351
|
+
<div class="alert alert-block alert-danger">
|
352
|
+
<ul>
|
353
|
+
<% @errors.full_messages.each do |msg| %>
|
354
|
+
<li><%= msg %></li>
|
355
|
+
<% end %>
|
356
|
+
</ul>
|
357
|
+
</div>
|
358
|
+
<% end %>
|
359
|
+
|
287
360
|
<div class="form-group">
|
288
361
|
<label class="control-label">Host</label>
|
289
362
|
<%= f.text_field :host, value: Setting.host, class: "form-control", placeholder: "http://localhost" %>
|
@@ -349,8 +422,12 @@ end
|
|
349
422
|
- [forem/forem](https://github.com/forem/forem) - 2.x
|
350
423
|
- [siwapp/siwapp](https://github.com/siwapp/siwapp) - 2.x
|
351
424
|
- [aidewoode/black_candy](https://github.com/aidewoode/black_candy) - 2.x
|
352
|
-
- [
|
425
|
+
- [huacnlee/bluedoc](https://github.com/huacnlee/bluedoc) - 2.x
|
426
|
+
- [getzealot/zealot](https://github.com/getzealot/zealot) - 2.x
|
427
|
+
- [kaishuu0123/rebacklogs](https://github.com/kaishuu0123/rebacklogs) - 2.x
|
428
|
+
- [texterify/texterify](https://github.com/texterify/texterify) - 2.x
|
353
429
|
- [tootsuite/mastodon](https://github.com/tootsuite/mastodon) - 0.6.x
|
354
430
|
- [helpyio/helpy](https://github.com/helpyio/helpy) - 0.5.x
|
431
|
+
- [daqing/rabel](https://github.com/daqing/rabel) - 0.4.x
|
355
432
|
|
356
433
|
And more than [1K repositories](https://github.com/huacnlee/rails-settings-cached/network/dependents) used.
|
data/lib/rails-settings/base.rb
CHANGED
@@ -4,11 +4,12 @@ module RailsSettings
|
|
4
4
|
class Base < ActiveRecord::Base
|
5
5
|
class SettingNotFound < RuntimeError; end
|
6
6
|
|
7
|
-
SEPARATOR_REGEXP = /[\n,;]
|
7
|
+
SEPARATOR_REGEXP = /[\n,;]+/
|
8
8
|
self.table_name = table_name_prefix + "settings"
|
9
9
|
|
10
10
|
# get the value field, YAML decoded
|
11
11
|
def value
|
12
|
+
# rubocop:disable Security/YAMLLoad
|
12
13
|
YAML.load(self[:value]) if self[:value].present?
|
13
14
|
end
|
14
15
|
|
@@ -23,12 +24,13 @@ module RailsSettings
|
|
23
24
|
|
24
25
|
class << self
|
25
26
|
def clear_cache
|
26
|
-
|
27
|
+
RequestCache.reset
|
27
28
|
Rails.cache.delete(cache_key)
|
28
29
|
end
|
29
30
|
|
30
31
|
def field(key, **opts)
|
31
|
-
_define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly],
|
32
|
+
_define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly],
|
33
|
+
separator: opts[:separator], validates: opts[:validates])
|
32
34
|
end
|
33
35
|
|
34
36
|
def get_field(key)
|
@@ -59,10 +61,12 @@ module RailsSettings
|
|
59
61
|
|
60
62
|
private
|
61
63
|
|
62
|
-
def _define_field(key, default: nil, type: :string, readonly: false, separator: nil)
|
64
|
+
def _define_field(key, default: nil, type: :string, readonly: false, separator: nil, validates: nil)
|
65
|
+
key = key.to_s
|
66
|
+
|
63
67
|
@defined_fields ||= []
|
64
68
|
@defined_fields << {
|
65
|
-
key: key
|
69
|
+
key: key,
|
66
70
|
default: default,
|
67
71
|
type: type || :string,
|
68
72
|
readonly: readonly.nil? ? false : readonly
|
@@ -70,7 +74,8 @@ module RailsSettings
|
|
70
74
|
|
71
75
|
if readonly
|
72
76
|
define_singleton_method(key) do
|
73
|
-
|
77
|
+
result = default.is_a?(Proc) ? default.call : default
|
78
|
+
send(:_convert_string_to_typeof_value, type, result, separator: separator)
|
74
79
|
end
|
75
80
|
else
|
76
81
|
define_singleton_method(key) do
|
@@ -89,7 +94,7 @@ module RailsSettings
|
|
89
94
|
end
|
90
95
|
|
91
96
|
define_singleton_method("#{key}=") do |value|
|
92
|
-
var_name = key
|
97
|
+
var_name = key
|
93
98
|
|
94
99
|
record = find_by(var: var_name) || new(var: var_name)
|
95
100
|
value = send(:_convert_string_to_typeof_value, type, value, separator: separator)
|
@@ -99,6 +104,15 @@ module RailsSettings
|
|
99
104
|
|
100
105
|
value
|
101
106
|
end
|
107
|
+
|
108
|
+
if validates
|
109
|
+
validates[:if] = proc { |item| item.var.to_s == key }
|
110
|
+
send(:validates, key, **validates)
|
111
|
+
|
112
|
+
define_method(:read_attribute_for_validation) do |_key|
|
113
|
+
self.value
|
114
|
+
end
|
115
|
+
end
|
102
116
|
end
|
103
117
|
|
104
118
|
if type == :boolean
|
@@ -113,19 +127,15 @@ module RailsSettings
|
|
113
127
|
|
114
128
|
case type
|
115
129
|
when :boolean
|
116
|
-
|
130
|
+
["true", "1", 1, true].include?(value)
|
117
131
|
when :array
|
118
132
|
value.split(separator || SEPARATOR_REGEXP).reject { |str| str.empty? }.map(&:strip)
|
119
133
|
when :hash
|
120
134
|
value = begin
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
126
|
-
rescue StandardError
|
127
|
-
{}
|
128
|
-
end
|
135
|
+
YAML.safe_load(value).to_h
|
136
|
+
rescue
|
137
|
+
{}
|
138
|
+
end
|
129
139
|
value.deep_stringify_keys!
|
130
140
|
ActiveSupport::HashWithIndifferentAccess.new(value)
|
131
141
|
when :integer
|
@@ -146,12 +156,12 @@ module RailsSettings
|
|
146
156
|
return nil
|
147
157
|
end
|
148
158
|
|
149
|
-
_all_settings[var_name
|
159
|
+
_all_settings[var_name]
|
150
160
|
end
|
151
161
|
|
152
162
|
def _table_exists?
|
153
163
|
table_exists?
|
154
|
-
rescue
|
164
|
+
rescue
|
155
165
|
false
|
156
166
|
end
|
157
167
|
|
@@ -160,13 +170,11 @@ module RailsSettings
|
|
160
170
|
end
|
161
171
|
|
162
172
|
def _all_settings
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
result.with_indifferent_access
|
169
|
-
end
|
173
|
+
RequestCache.settings ||= Rails.cache.fetch(cache_key, expires_in: 1.week) do
|
174
|
+
vars = unscoped.select("var, value")
|
175
|
+
result = {}
|
176
|
+
vars.each { |record| result[record.var] = record.value }
|
177
|
+
result.with_indifferent_access
|
170
178
|
end
|
171
179
|
end
|
172
180
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RailsSettings
|
4
4
|
class Railtie < Rails::Railtie
|
5
5
|
initializer "rails_settings.active_record.initialization" do
|
6
|
-
RailsSettings::Base.after_commit :clear_cache, on: %i
|
6
|
+
RailsSettings::Base.after_commit :clear_cache, on: %i[create update destroy]
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RailsSettings
|
2
|
+
if defined? ActiveSupport::CurrentAttributes
|
3
|
+
# For storage all settings in Current, it will reset after per request completed.
|
4
|
+
# Base on ActiveSupport::CurrentAttributes
|
5
|
+
# https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html
|
6
|
+
class RequestCache < ActiveSupport::CurrentAttributes
|
7
|
+
attribute :settings
|
8
|
+
end
|
9
|
+
else
|
10
|
+
# https://github.com/steveklabnik/request_store
|
11
|
+
# For Rails 5.0
|
12
|
+
require "request_store"
|
13
|
+
|
14
|
+
class RequestCache
|
15
|
+
class << self
|
16
|
+
def reset
|
17
|
+
self.settings = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def settings
|
21
|
+
RequestStore.store[:rails_settings_all_settings]
|
22
|
+
end
|
23
|
+
|
24
|
+
def settings=(val)
|
25
|
+
RequestStore.store[:rails_settings_all_settings]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
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.
|
4
|
+
version: 2.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Lee
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 5.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: codecov
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,11 +108,11 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
-
description: "\n
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
111
|
+
description: "\n The best solution for store global settings in Rails applications.\n\n
|
112
|
+
\ This gem will managing a table of а global key, value pairs easy. Think of it
|
113
|
+
like a\n global Hash stored in your database, that uses simple ActiveRecord like
|
114
|
+
methods for manipulation.\n\n Keep track of any global setting that you dont want
|
115
|
+
to hard code into your rails app.\n You can store any kind of object. Strings,
|
116
116
|
numbers, arrays, or any object.\n "
|
117
117
|
email: huacnlee@gmail.com
|
118
118
|
executables: []
|
@@ -128,13 +128,13 @@ files:
|
|
128
128
|
- lib/rails-settings-cached.rb
|
129
129
|
- lib/rails-settings/base.rb
|
130
130
|
- lib/rails-settings/railtie.rb
|
131
|
-
- lib/rails-settings/
|
131
|
+
- lib/rails-settings/request_cache.rb
|
132
132
|
- lib/rails-settings/version.rb
|
133
133
|
homepage: https://github.com/huacnlee/rails-settings-cached
|
134
134
|
licenses:
|
135
135
|
- MIT
|
136
136
|
metadata: {}
|
137
|
-
post_install_message:
|
137
|
+
post_install_message:
|
138
138
|
rdoc_options: []
|
139
139
|
require_paths:
|
140
140
|
- lib
|
@@ -149,8 +149,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
149
|
- !ruby/object:Gem::Version
|
150
150
|
version: '0'
|
151
151
|
requirements: []
|
152
|
-
rubygems_version: 3.
|
153
|
-
signing_key:
|
152
|
+
rubygems_version: 3.2.3
|
153
|
+
signing_key:
|
154
154
|
specification_version: 4
|
155
|
-
summary:
|
155
|
+
summary: The best solution for store global settings in Rails applications.
|
156
156
|
test_files: []
|
@@ -1,8 +0,0 @@
|
|
1
|
-
module RailsSettings
|
2
|
-
# For storage all settings in Current, it will reset after per request completed.
|
3
|
-
# Base on ActiveSupport::CurrentAttributes
|
4
|
-
# https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html
|
5
|
-
class RequestStore < ActiveSupport::CurrentAttributes
|
6
|
-
attribute :settings
|
7
|
-
end
|
8
|
-
end
|