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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29703d30ef00244c99b49047ce3a05edd212ee71a23433cb581d5bf69c6a02c6
4
- data.tar.gz: 7f1d2dffdf1c552faca1b7afdbaaeaa52039897afb5364b8aef37de3d93389c4
3
+ metadata.gz: 70c3d68c88fbd1a2a3cc1e9f78a45e06fc7b7a6df4698137e2a4ea6c77a27e33
4
+ data.tar.gz: fd6ecee62edad7a5ca942fbe7e102ae6e3f075ea471e120dcc5a5f1d5f3fdb33
5
5
  SHA512:
6
- metadata.gz: 6e1b41ac975dd31fadf90c5d9c059542aaeb09a0bfbf3f137266a32ae58c30557afedbe33c775af9a2683a8f8b56b85ee0f94b4a063a27e5c79176b5c1714d0d
7
- data.tar.gz: a5ee74e8dd391aab429db68904b5d78a79581fd41de6304aece887fcdf9be8b023f4fff03a2fedbfdbc81cff964be5b695a90c5e4c3f908d49bed01c0fb70f83
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) [![CI Status](https://travis-ci.org/huacnlee/rails-settings-cached.svg)](http://travis-ci.org/huacnlee/rails-settings-cached) [![codecov.io](https://codecov.io/github/huacnlee/rails-settings-cached/coverage.svg?branch=master)](https://codecov.io/github/huacnlee/rails-settings-cached?branch=master)
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
- # Override array separator, default: /[\n,]/ split with \n or comma.
43
- field :tips, type: :array, separator: /[\n]+/
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
- # lambda default value
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 options of field
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
@@ -1,14 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsSettings
4
- class Base < ActiveRecord::Base
5
- class SettingNotFound < RuntimeError; end
4
+ class ProcetedKeyError < RuntimeError
5
+ def initialize(key)
6
+ super("Can't use #{key} as setting key.")
7
+ end
8
+ end
6
9
 
7
- SEPARATOR_REGEXP = /[\n,;]+/.freeze
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, default: opts[:default], type: opts[:type], readonly: opts[:readonly], separator: opts[:separator], validates: opts[:validates])
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
- scope = ["rails-settings-cached"]
44
- scope << @cache_prefix.call if @cache_prefix
45
- scope.join("/")
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
- key: key.to_s,
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
- send(:_convert_string_to_typeof_value, type, default, separator: separator)
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.to_s
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] = Proc.new { |item| item.var.to_s == key.to_s }
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
- value == "true" || value == "1" || value == 1 || value == true
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
- begin
131
- YAML.load(value).to_h
132
- rescue StandardError
133
- eval(value).to_h
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.to_s]
189
+ _all_settings[var_name]
159
190
  end
160
191
 
161
192
  def _table_exists?
162
193
  table_exists?
163
- rescue => e
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 ||= begin
173
- 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
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(create update destroy)
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
@@ -3,7 +3,7 @@
3
3
  module RailsSettings
4
4
  class << self
5
5
  def version
6
- "2.5.1"
6
+ "2.7.1"
7
7
  end
8
8
  end
9
9
  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.5.1
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: 2020-12-09 00:00:00.000000000 Z
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 \n global Hash stored in your database, that uses simple ActiveRecord like
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.0
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: []