rails-settings-cached 2.5.3 → 2.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc604a3e9ea5a7ed498250820ca7e93ec44e38adb88380b24b0f7b2d5dc164b8
4
- data.tar.gz: 9e62d3f49c59e981655a22924d2c32d346ba4618a6c98b4b8b1a0dfb6fd6db24
3
+ metadata.gz: 5f078f79f76ec1145cb095d269ea6a4772e8959b0eeaedec1ed607a23189fc5b
4
+ data.tar.gz: bd0105aebf763f4bce9041c459f6464f827ce1459ed3b83614342f1f285bfe7d
5
5
  SHA512:
6
- metadata.gz: 7bfc23cb9fadddad15c1f3c341973bae5571cdb324ebb7d71f8c075c3877912d7f40b2792cbeaa582a79f22bcde166def831506c95d90444cd7193077492d4a7
7
- data.tar.gz: dc55136872ad58751d08f745d93a7707e3e815f6ffc99adcc5d63b19e980594a7874c11484976b7342932ca511ace408c8d48bdd5de5666854b544d908345678
6
+ metadata.gz: 964dad7734883af92b76ed7e4b6729e7381f15b3e2149df7fc98e07dbf869baef1460e0f0dea6de6eb0689255a4e249d55e2afdd7fdf5f3d18b0028ac407caa3
7
+ data.tar.gz: a1bc23575e4790b2c707bc644fb5d522c95338320120cb1bab1b047310c868ec7922e29853d138dc137726f75bce25f518f95a5b71a146d3e4da8b613807cb5a
data/README.md CHANGED
@@ -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
@@ -257,6 +283,10 @@ Rails.application.configure do
257
283
  end
258
284
  ```
259
285
 
286
+ TIP: You also can follow this file to rewrite ActionMailer's `mail` method for configuration Mail options from Setting after Rails booted.
287
+
288
+ https://github.com/ruby-china/homeland/blob/main/app/mailers/application_mailer.rb#L19
289
+
260
290
  ## Caching flow:
261
291
 
262
292
  ```
@@ -1,10 +1,15 @@
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
 
10
+ class Base < ActiveRecord::Base
7
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
@@ -29,8 +34,20 @@ module RailsSettings
29
34
  end
30
35
 
31
36
  def field(key, **opts)
32
- _define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly],
33
- 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
34
51
  end
35
52
 
36
53
  def get_field(key)
@@ -42,9 +59,9 @@ module RailsSettings
42
59
  end
43
60
 
44
61
  def cache_key
45
- scope = ["rails-settings-cached"]
46
- scope << @cache_prefix.call if @cache_prefix
47
- scope.join("/")
62
+ key_parts = ["rails-settings-cached"]
63
+ key_parts << @cache_prefix.call if @cache_prefix
64
+ key_parts.join("/")
48
65
  end
49
66
 
50
67
  def keys
@@ -59,17 +76,23 @@ module RailsSettings
59
76
  @defined_fields.select { |field| field[:readonly] }.map { |field| field[:key] }
60
77
  end
61
78
 
79
+ attr_reader :defined_fields
80
+
62
81
  private
63
82
 
64
- 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)
65
84
  key = key.to_s
66
85
 
86
+ raise ProcetedKeyError.new(key) if PROTECTED_KEYS.include?(key)
87
+
67
88
  @defined_fields ||= []
68
89
  @defined_fields << {
90
+ scope: @scope,
69
91
  key: key,
70
92
  default: default,
71
93
  type: type || :string,
72
- readonly: readonly.nil? ? false : readonly
94
+ readonly: readonly.nil? ? false : readonly,
95
+ options: opts
73
96
  }
74
97
 
75
98
  if readonly
@@ -120,6 +143,13 @@ module RailsSettings
120
143
  send(key)
121
144
  end
122
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
123
153
  end
124
154
 
125
155
  def _convert_string_to_typeof_value(type, value, separator: nil)
@@ -170,7 +200,7 @@ module RailsSettings
170
200
  end
171
201
 
172
202
  def _all_settings
173
- RequestCache.settings ||= Rails.cache.fetch(cache_key, expires_in: 1.week) do
203
+ RequestCache.all_settings ||= Rails.cache.fetch(cache_key, expires_in: 1.week) do
174
204
  vars = unscoped.select("var, value")
175
205
  result = {}
176
206
  vars.each { |record| result[record.var] = record.value }
@@ -0,0 +1,14 @@
1
+ module RailsSettings
2
+ class Middleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ RailsSettings::RequestCache.enable!
9
+ result = @app.call(env)
10
+ RailsSettings::RequestCache.disable!
11
+ result
12
+ end
13
+ end
14
+ end
@@ -5,5 +5,9 @@ module RailsSettings
5
5
  initializer "rails_settings.active_record.initialization" do
6
6
  RailsSettings::Base.after_commit :clear_cache, on: %i[create update destroy]
7
7
  end
8
+
9
+ initializer "rails_settings.configure_rails_initialization" do |app|
10
+ app.middleware.use RailsSettings::Middleware
11
+ end
8
12
  end
9
13
  end
@@ -1,9 +1,36 @@
1
1
  module RailsSettings
2
+ module RequestCacheGetter
3
+ extend ActiveSupport::Concern
4
+
5
+ class_methods do
6
+ def enable!
7
+ Thread.current[:rails_settings_request_cache_enable] = true
8
+ end
9
+
10
+ def disable!
11
+ Thread.current[:rails_settings_request_cache_enable] = nil
12
+ end
13
+
14
+ def enabled?
15
+ Thread.current[:rails_settings_request_cache_enable]
16
+ end
17
+
18
+ def all_settings
19
+ enabled? ? settings : nil
20
+ end
21
+
22
+ def all_settings=(val)
23
+ self.settings = val
24
+ end
25
+ end
26
+ end
27
+
2
28
  if defined? ActiveSupport::CurrentAttributes
3
29
  # For storage all settings in Current, it will reset after per request completed.
4
30
  # Base on ActiveSupport::CurrentAttributes
5
31
  # https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html
6
32
  class RequestCache < ActiveSupport::CurrentAttributes
33
+ include RequestCacheGetter
7
34
  attribute :settings
8
35
  end
9
36
  else
@@ -12,6 +39,8 @@ module RailsSettings
12
39
  require "request_store"
13
40
 
14
41
  class RequestCache
42
+ include RequestCacheGetter
43
+
15
44
  class << self
16
45
  def reset
17
46
  self.settings = nil
@@ -3,7 +3,7 @@
3
3
  module RailsSettings
4
4
  class << self
5
5
  def version
6
- "2.5.3"
6
+ "2.8.0"
7
7
  end
8
8
  end
9
9
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "rails-settings/base"
4
4
  require_relative "rails-settings/request_cache"
5
+ require_relative "rails-settings/middleware"
5
6
  require_relative "rails-settings/railtie"
6
7
  require_relative "rails-settings/version"
7
8
 
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.3
4
+ version: 2.8.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: 2021-06-21 00:00:00.000000000 Z
11
+ date: 2021-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 5.0.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: codecov
28
+ name: pg
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: pg
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: rubocop
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,20 +66,6 @@ dependencies:
80
66
  - - ">="
81
67
  - !ruby/object:Gem::Version
82
68
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: simplecov
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
69
  - !ruby/object:Gem::Dependency
98
70
  name: sqlite3
99
71
  requirement: !ruby/object:Gem::Requirement
@@ -127,6 +99,7 @@ files:
127
99
  - lib/generators/settings/templates/model.rb
128
100
  - lib/rails-settings-cached.rb
129
101
  - lib/rails-settings/base.rb
102
+ - lib/rails-settings/middleware.rb
130
103
  - lib/rails-settings/railtie.rb
131
104
  - lib/rails-settings/request_cache.rb
132
105
  - lib/rails-settings/version.rb
@@ -149,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
122
  - !ruby/object:Gem::Version
150
123
  version: '0'
151
124
  requirements: []
152
- rubygems_version: 3.2.3
125
+ rubygems_version: 3.1.4
153
126
  signing_key:
154
127
  specification_version: 4
155
128
  summary: The best solution for store global settings in Rails applications.