rails-settings-cached 2.5.1 → 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +44 -17
- data/lib/rails-settings/base.rb +60 -31
- data/lib/rails-settings/railtie.rb +1 -1
- data/lib/rails-settings/request_cache.rb +3 -3
- data/lib/rails-settings/version.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70c3d68c88fbd1a2a3cc1e9f78a45e06fc7b7a6df4698137e2a4ea6c77a27e33
|
4
|
+
data.tar.gz: fd6ecee62edad7a5ca942fbe7e102ae6e3f075ea471e120dcc5a5f1d5f3fdb33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d0c55d7a8f19adbfa81868c76a1d36f67aa37d27ad33051b7a8bf6ec323d0d4b57cc442c29b43be8c8799cfa3968f958f29fb1f104230dc79478294f09d2a59
|
7
|
+
data.tar.gz: 699e9e77f1d4d130e9493c7c379f1aade95b7f589401652912741f5e13eec4816b0a8eee308b55504ad3acfc2613af41113051d6a5655df399d27ed59015bd5f
|
data/README.md
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
The best solution for store global settings in Rails applications.
|
4
4
|
|
5
|
-
This gem will 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.
|
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
6
|
|
7
7
|
You can store any kind of object. Strings, numbers, arrays, booleans, or any object.
|
8
8
|
|
9
|
-
[![Gem Version](https://badge.fury.io/rb/rails-settings-cached.svg)](https://rubygems.org/gems/rails-settings-cached) [![
|
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,17 +30,24 @@ 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", validates: { presence: true, length: { in: 2..20 } }
|
34
|
-
field :host, default: "http://example.com", readonly: true
|
35
|
-
field :default_locale, default: "zh-CN", validates: { presence: true, inclusion: { in: %w[zh-CN en jp] } }
|
36
|
-
field :readonly_item, type: :integer, default: 100, readonly: true
|
37
|
-
field :user_limits, type: :integer, default: 20
|
38
|
-
field :exchange_rate, type: :float, default: 0.123
|
39
|
-
field :admin_emails, type: :array, default: %w[admin@rubyonrails.org]
|
40
|
-
field :captcha_enable, type: :boolean, default: true
|
41
33
|
|
42
|
-
|
43
|
-
|
34
|
+
scope :application do
|
35
|
+
field :app_name, default: "Rails Settings", validates: { presence: true, length: { in: 2..20 } }
|
36
|
+
field :host, default: "http://example.com", readonly: true
|
37
|
+
field :default_locale, default: "zh-CN", validates: { presence: true, inclusion: { in: %w[zh-CN en jp] } }, option_values: %w[en zh-CN jp], help_text: "Bla bla ..."
|
38
|
+
field :admin_emails, type: :array, default: %w[admin@rubyonrails.org]
|
39
|
+
|
40
|
+
# lambda default value
|
41
|
+
field :welcome_message, type: :string, default: -> { "welcome to #{self.app_name}" }, validates: { length: { maximum: 255 } }
|
42
|
+
# Override array separator, default: /[\n,]/ split with \n or comma.
|
43
|
+
field :tips, type: :array, separator: /[\n]+/
|
44
|
+
end
|
45
|
+
|
46
|
+
scope :limits do
|
47
|
+
field :user_limits, type: :integer, default: 20
|
48
|
+
field :exchange_rate, type: :float, default: 0.123
|
49
|
+
field :captcha_enable, type: :boolean, default: true
|
50
|
+
end
|
44
51
|
|
45
52
|
field :notification_options, type: :hash, default: {
|
46
53
|
send_all: true,
|
@@ -48,13 +55,14 @@ class Setting < RailsSettings::Base
|
|
48
55
|
sender_email: "foo@bar.com"
|
49
56
|
}
|
50
57
|
|
51
|
-
|
52
|
-
field :welcome_message, type: :string, default: -> { "welcome to #{self.app_name}" }, validates: { length: { maximum: 255 } }
|
58
|
+
field :readonly_item, type: :integer, default: 100, readonly: true
|
53
59
|
end
|
54
60
|
```
|
55
61
|
|
56
62
|
You must use the `field` method to statement the setting keys, otherwise you can't use it.
|
57
63
|
|
64
|
+
The `scope` method allows you to group the keys for admin UI.
|
65
|
+
|
58
66
|
Now just put that migration in the database with:
|
59
67
|
|
60
68
|
```bash
|
@@ -143,11 +151,29 @@ Settng.editable_keys
|
|
143
151
|
Setting.readonly_keys
|
144
152
|
=> ["host", "readonly_item"]
|
145
153
|
|
146
|
-
# Get
|
154
|
+
# Get field
|
147
155
|
Setting.get_field("host")
|
148
|
-
=> { key: "host", type: :string, default: "http://example.com", readonly: true }
|
156
|
+
=> { scope: :application, key: "host", type: :string, default: "http://example.com", readonly: true }
|
149
157
|
Setting.get_field("app_name")
|
150
|
-
=> { key: "app_name", type: :string, default: "Rails Settings", readonly: false }
|
158
|
+
=> { scope: :application, key: "app_name", type: :string, default: "Rails Settings", readonly: false }
|
159
|
+
Setting.get_field(:user_limits)
|
160
|
+
=> { scope: :limits, key: "user_limits", type: :integer, default: 20, readonly: false }
|
161
|
+
# Get field options
|
162
|
+
Setting.get_field("default_locale")[:options]
|
163
|
+
=> { option_values: %w[en zh-CN jp], help_text: "Bla bla ..." }
|
164
|
+
```
|
165
|
+
|
166
|
+
#### Get All defined fields
|
167
|
+
|
168
|
+
> version 2.7.0+
|
169
|
+
|
170
|
+
You can use `defined_fields` method to get all defined fields in Setting.
|
171
|
+
|
172
|
+
```rb
|
173
|
+
# Get editable fields and group by scope
|
174
|
+
editable_fields = Setting.defined_fields
|
175
|
+
.select { |field| !field[:readonly] }
|
176
|
+
.group_by { |field| field[:scope] }
|
151
177
|
```
|
152
178
|
|
153
179
|
## Validations
|
@@ -425,6 +451,7 @@ end
|
|
425
451
|
- [huacnlee/bluedoc](https://github.com/huacnlee/bluedoc) - 2.x
|
426
452
|
- [getzealot/zealot](https://github.com/getzealot/zealot) - 2.x
|
427
453
|
- [kaishuu0123/rebacklogs](https://github.com/kaishuu0123/rebacklogs) - 2.x
|
454
|
+
- [texterify/texterify](https://github.com/texterify/texterify) - 2.x
|
428
455
|
- [tootsuite/mastodon](https://github.com/tootsuite/mastodon) - 0.6.x
|
429
456
|
- [helpyio/helpy](https://github.com/helpyio/helpy) - 0.5.x
|
430
457
|
- [daqing/rabel](https://github.com/daqing/rabel) - 0.4.x
|
data/lib/rails-settings/base.rb
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsSettings
|
4
|
-
class
|
5
|
-
|
4
|
+
class ProcetedKeyError < RuntimeError
|
5
|
+
def initialize(key)
|
6
|
+
super("Can't use #{key} as setting key.")
|
7
|
+
end
|
8
|
+
end
|
6
9
|
|
7
|
-
|
10
|
+
class Base < ActiveRecord::Base
|
11
|
+
SEPARATOR_REGEXP = /[\n,;]+/
|
12
|
+
PROTECTED_KEYS = %w[var value]
|
8
13
|
self.table_name = table_name_prefix + "settings"
|
9
14
|
|
10
15
|
# get the value field, YAML decoded
|
11
16
|
def value
|
17
|
+
# rubocop:disable Security/YAMLLoad
|
12
18
|
YAML.load(self[:value]) if self[:value].present?
|
13
19
|
end
|
14
20
|
|
@@ -28,7 +34,20 @@ module RailsSettings
|
|
28
34
|
end
|
29
35
|
|
30
36
|
def field(key, **opts)
|
31
|
-
_define_field(key,
|
37
|
+
_define_field(key, **opts)
|
38
|
+
end
|
39
|
+
|
40
|
+
alias_method :_rails_scope, :scope
|
41
|
+
def scope(*args, &block)
|
42
|
+
name = args.shift
|
43
|
+
body = args.shift
|
44
|
+
if body.respond_to?(:call)
|
45
|
+
return _rails_scope(name, body, &block)
|
46
|
+
end
|
47
|
+
|
48
|
+
@scope = name.to_sym
|
49
|
+
yield block
|
50
|
+
@scope = nil
|
32
51
|
end
|
33
52
|
|
34
53
|
def get_field(key)
|
@@ -40,9 +59,9 @@ module RailsSettings
|
|
40
59
|
end
|
41
60
|
|
42
61
|
def cache_key
|
43
|
-
|
44
|
-
|
45
|
-
|
62
|
+
key_parts = ["rails-settings-cached"]
|
63
|
+
key_parts << @cache_prefix.call if @cache_prefix
|
64
|
+
key_parts.join("/")
|
46
65
|
end
|
47
66
|
|
48
67
|
def keys
|
@@ -57,20 +76,29 @@ module RailsSettings
|
|
57
76
|
@defined_fields.select { |field| field[:readonly] }.map { |field| field[:key] }
|
58
77
|
end
|
59
78
|
|
79
|
+
attr_reader :defined_fields
|
80
|
+
|
60
81
|
private
|
61
82
|
|
62
|
-
def _define_field(key, default: nil, type: :string, readonly: false, separator: nil, validates: nil)
|
83
|
+
def _define_field(key, default: nil, type: :string, readonly: false, separator: nil, validates: nil, **opts)
|
84
|
+
key = key.to_s
|
85
|
+
|
86
|
+
raise ProcetedKeyError.new(key) if PROTECTED_KEYS.include?(key)
|
87
|
+
|
63
88
|
@defined_fields ||= []
|
64
89
|
@defined_fields << {
|
65
|
-
|
90
|
+
scope: @scope,
|
91
|
+
key: key,
|
66
92
|
default: default,
|
67
93
|
type: type || :string,
|
68
|
-
readonly: readonly.nil? ? false : readonly
|
94
|
+
readonly: readonly.nil? ? false : readonly,
|
95
|
+
options: opts
|
69
96
|
}
|
70
97
|
|
71
98
|
if readonly
|
72
99
|
define_singleton_method(key) do
|
73
|
-
|
100
|
+
result = default.is_a?(Proc) ? default.call : default
|
101
|
+
send(:_convert_string_to_typeof_value, type, result, separator: separator)
|
74
102
|
end
|
75
103
|
else
|
76
104
|
define_singleton_method(key) do
|
@@ -89,7 +117,7 @@ module RailsSettings
|
|
89
117
|
end
|
90
118
|
|
91
119
|
define_singleton_method("#{key}=") do |value|
|
92
|
-
var_name = key
|
120
|
+
var_name = key
|
93
121
|
|
94
122
|
record = find_by(var: var_name) || new(var: var_name)
|
95
123
|
value = send(:_convert_string_to_typeof_value, type, value, separator: separator)
|
@@ -101,7 +129,7 @@ module RailsSettings
|
|
101
129
|
end
|
102
130
|
|
103
131
|
if validates
|
104
|
-
validates[:if] =
|
132
|
+
validates[:if] = proc { |item| item.var.to_s == key }
|
105
133
|
send(:validates, key, **validates)
|
106
134
|
|
107
135
|
define_method(:read_attribute_for_validation) do |_key|
|
@@ -115,6 +143,13 @@ module RailsSettings
|
|
115
143
|
send(key)
|
116
144
|
end
|
117
145
|
end
|
146
|
+
|
147
|
+
# delegate instance get method to class for support:
|
148
|
+
# setting = Setting.new
|
149
|
+
# setting.admin_emails
|
150
|
+
define_method(key) do
|
151
|
+
self.class.public_send(key)
|
152
|
+
end
|
118
153
|
end
|
119
154
|
|
120
155
|
def _convert_string_to_typeof_value(type, value, separator: nil)
|
@@ -122,19 +157,15 @@ module RailsSettings
|
|
122
157
|
|
123
158
|
case type
|
124
159
|
when :boolean
|
125
|
-
|
160
|
+
["true", "1", 1, true].include?(value)
|
126
161
|
when :array
|
127
162
|
value.split(separator || SEPARATOR_REGEXP).reject { |str| str.empty? }.map(&:strip)
|
128
163
|
when :hash
|
129
164
|
value = begin
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
end
|
135
|
-
rescue StandardError
|
136
|
-
{}
|
137
|
-
end
|
165
|
+
YAML.safe_load(value).to_h
|
166
|
+
rescue
|
167
|
+
{}
|
168
|
+
end
|
138
169
|
value.deep_stringify_keys!
|
139
170
|
ActiveSupport::HashWithIndifferentAccess.new(value)
|
140
171
|
when :integer
|
@@ -155,12 +186,12 @@ module RailsSettings
|
|
155
186
|
return nil
|
156
187
|
end
|
157
188
|
|
158
|
-
_all_settings[var_name
|
189
|
+
_all_settings[var_name]
|
159
190
|
end
|
160
191
|
|
161
192
|
def _table_exists?
|
162
193
|
table_exists?
|
163
|
-
rescue
|
194
|
+
rescue
|
164
195
|
false
|
165
196
|
end
|
166
197
|
|
@@ -169,13 +200,11 @@ module RailsSettings
|
|
169
200
|
end
|
170
201
|
|
171
202
|
def _all_settings
|
172
|
-
RequestCache.settings ||=
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
result.with_indifferent_access
|
178
|
-
end
|
203
|
+
RequestCache.settings ||= Rails.cache.fetch(cache_key, expires_in: 1.week) do
|
204
|
+
vars = unscoped.select("var, value")
|
205
|
+
result = {}
|
206
|
+
vars.each { |record| result[record.var] = record.value }
|
207
|
+
result.with_indifferent_access
|
179
208
|
end
|
180
209
|
end
|
181
210
|
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
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module RailsSettings
|
2
|
-
if defined? ActiveSupport::CurrentAttributes
|
2
|
+
if defined? ActiveSupport::CurrentAttributes
|
3
3
|
# For storage all settings in Current, it will reset after per request completed.
|
4
4
|
# Base on ActiveSupport::CurrentAttributes
|
5
5
|
# https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html
|
6
|
-
class RequestCache < ActiveSupport::CurrentAttributes
|
6
|
+
class RequestCache < ActiveSupport::CurrentAttributes
|
7
7
|
attribute :settings
|
8
8
|
end
|
9
9
|
else
|
@@ -27,4 +27,4 @@ module RailsSettings
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
|
-
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.7.1
|
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-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -110,7 +110,7 @@ dependencies:
|
|
110
110
|
version: '0'
|
111
111
|
description: "\n The best solution for store global settings in Rails applications.\n\n
|
112
112
|
\ This gem will managing a table of а global key, value pairs easy. Think of it
|
113
|
-
like a
|
113
|
+
like a\n global Hash stored in your database, that uses simple ActiveRecord like
|
114
114
|
methods for manipulation.\n\n Keep track of any global setting that you dont want
|
115
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 "
|
@@ -134,7 +134,7 @@ 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.2.
|
153
|
-
signing_key:
|
152
|
+
rubygems_version: 3.2.3
|
153
|
+
signing_key:
|
154
154
|
specification_version: 4
|
155
155
|
summary: The best solution for store global settings in Rails applications.
|
156
156
|
test_files: []
|