rails-settings-cached 2.5.3 → 2.8.0

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: 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.