rails-settings-cached 2.2.1 → 2.3.5

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: 85279c41b179aa65d668a48d4d18e73b5fe886be9cd8235dc2acdb54c3beb5da
4
- data.tar.gz: 516991953aa7698cf86511512d863b7903d1ec5ad648a69c386501413a75ac86
3
+ metadata.gz: 23b68e0d113892e9f08e29c3e70e39d79f3ce58aed36a981c55fe81593b8f3a9
4
+ data.tar.gz: c144240c649762ee4495fee8e2eef504244ae37746e43c294cef3512ea813a4c
5
5
  SHA512:
6
- metadata.gz: 742596dc7e47c3d31ea64ecf54d96cae5885938076c2704aebe5f3e94701627631d19a8480f24ef97dc1861a8e1a1cab33c6f3aefd56ff755f88ef47c1380401
7
- data.tar.gz: aa7b9a3ba2443a7ac6cb12150c196247bfd543e086b4eea1199f83eca1035ddefc1bcb32ae5d01cf9c3448dcd2f5c651dd9a73c8dab22600d28f202ef7d1f4a6
6
+ metadata.gz: f094b5b2485041c04885b1097715bf046e3a5525b88d800242479edaa3190fba4b3f164729840f2b11c519862387893c69ce58085d5867deab74093f75bfee1b
7
+ data.tar.gz: 20d36398a118661a50d45cbfbc16b416f280ef46376c96acbae2a15226ac1f2c70483adcdaacc56530169d6a96ad1e9ac4f79234766c13e2e80a5faaf5e289f6
data/README.md CHANGED
@@ -30,8 +30,8 @@ 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 Cache Demo"
34
- field :host, default: "http://example.com"
33
+ field :app_name, default: "Rails Settings"
34
+ field :host, default: "http://example.com", readonly: true
35
35
  field :default_locale, default: "zh-CN"
36
36
  field :readonly_item, type: :integer, default: 100, readonly: true
37
37
  field :user_limits, type: :integer, default: 20
@@ -68,9 +68,11 @@ The syntax is easy. First, let's create some settings to keep track of:
68
68
  ```ruby
69
69
  irb > Setting.host
70
70
  "http://example.com"
71
- irb > Setting.host = "https://your-host.com"
72
- irb > Setting.host
73
- "https://your-host.com"
71
+ irb > Setting.app_name
72
+ "Rails Settings"
73
+ irb > Setting.app_name = "Rails Settings Cached"
74
+ irb > Setting.app_name
75
+ "Rails Settings Cached"
74
76
 
75
77
  irb > Setting.user_limits
76
78
  20
@@ -124,9 +126,36 @@ irb > Setting.notification_options
124
126
  }
125
127
  ```
126
128
 
127
- ## Readonly field
128
129
 
129
- Sometimes you may need to use Setting before Rails is initialized, for example `config/devise.rb`
130
+ ### Get defined fields
131
+
132
+ > version 2.3+
133
+
134
+ ```rb
135
+ # Get all keys
136
+ Setting.keys
137
+ => ["app_name", "host", "default_locale", "readonly_item"]
138
+
139
+ # Get editable keys
140
+ Settng.editable_keys
141
+ => ["app_name", "default_locale"]
142
+
143
+ # Get readonly keys
144
+ Setting.readonly_keys
145
+ => ["host", "readonly_item"]
146
+
147
+ # Get options of field
148
+ Setting.get_field("host")
149
+ => { key: "host", type: :string, default: "http://example.com", readonly: true }
150
+ Setting.get_field("app_name")
151
+ => { key: "app_name", type: :string, default: "Rails Settings", readonly: false }
152
+ ```
153
+
154
+ ## Use Setting in Rails initalizing:
155
+
156
+ In `version 2.3+` we allows you to use Setting before Rails is initialized.
157
+
158
+ For example `config/initializers/devise.rb`
130
159
 
131
160
  ```rb
132
161
  Devise.setup do |config|
@@ -136,13 +165,45 @@ Devise.setup do |config|
136
165
  end
137
166
  ```
138
167
 
139
- In this case, you must define the `readonly` field:
168
+ ```rb
169
+ class Setting < RailsSettings::Base
170
+ field :omniauth_google_client_id, default: ENV["OMNIAUTH_GOOGLE_CLIENT_ID"]
171
+ field :omniauth_google_client_secret, default: ENV["OMNIAUTH_GOOGLE_CLIENT_SECRET"]
172
+ end
173
+ ```
174
+
175
+ ## Readonly field
176
+
177
+ You may also want use Setting in these locations:
178
+
179
+ ```
180
+ config/application.rb
181
+ config/environments/*.rb
182
+ ```
183
+
184
+ If you want do that do that, the setting field must has `readonly: true`.
185
+
186
+ For example:
140
187
 
141
188
  ```rb
142
189
  class Setting < RailsSettings::Base
143
- # cache_prefix { "v1" }
144
- field :omniauth_google_client_id, default: ENV["OMNIAUTH_GOOGLE_CLIENT_ID"], readonly: true
145
- field :omniauth_google_client_secret, default: ENV["OMNIAUTH_GOOGLE_CLIENT_SECRET"], readonly: true
190
+ field :mailer_provider, default: (ENV["mailer_provider"] || "smtp"), readonly: true
191
+ field :mailer_options, type: :hash, readonly: true, default: {
192
+ address: ENV["mailer_options.address"],
193
+ port: ENV["mailer_options.port"],
194
+ domain: ENV["mailer_options.domain"],
195
+ user_name: ENV["mailer_options.user_name"],
196
+ password: ENV["mailer_options.password"],
197
+ authentication: ENV["mailer_options.authentication"] || "login",
198
+ enable_starttls_auto: ENV["mailer_options.enable_starttls_auto"]
199
+ }
200
+ end
201
+ ```
202
+
203
+ ```rb
204
+ Rails.application.configure do
205
+ config.action_mailer.delivery_method = :smtp
206
+ config.action_mailer.smtp_settings = Setting.mailer_options.deep_symbolize_keys
146
207
  end
147
208
  ```
148
209
 
@@ -6,7 +6,7 @@ module RailsSettings
6
6
  class Base < ActiveRecord::Base
7
7
  class SettingNotFound < RuntimeError; end
8
8
 
9
- SEPARATOR_REGEXP = /[\n,;]+/
9
+ SEPARATOR_REGEXP = /[\n,;]+/.freeze
10
10
  self.table_name = table_name_prefix + "settings"
11
11
 
12
12
  # get the value field, YAML decoded
@@ -26,15 +26,17 @@ module RailsSettings
26
26
  class << self
27
27
  def clear_cache
28
28
  RequestStore.store[:rails_settings_all_settings] = nil
29
- Rails.cache.delete(self.cache_key)
29
+ Rails.cache.delete(cache_key)
30
30
  end
31
31
 
32
32
  def field(key, **opts)
33
- @keys ||= []
34
- @keys << key.to_s
35
33
  _define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly], separator: opts[:separator])
36
34
  end
37
35
 
36
+ def get_field(key)
37
+ @defined_fields.find { |field| field[:key] == key.to_s } || {}
38
+ end
39
+
38
40
  def cache_prefix(&block)
39
41
  @cache_prefix = block
40
42
  end
@@ -46,96 +48,129 @@ module RailsSettings
46
48
  end
47
49
 
48
50
  def keys
49
- @keys
51
+ @defined_fields.map { |field| field[:key] }
52
+ end
53
+
54
+ def editable_keys
55
+ @defined_fields.reject { |field| field[:readonly] }.map { |field| field[:key] }
56
+ end
57
+
58
+ def readonly_keys
59
+ @defined_fields.select { |field| field[:readonly] }.map { |field| field[:key] }
50
60
  end
51
61
 
52
62
  private
53
63
 
54
- def _define_field(key, default: nil, type: :string, readonly: false, separator: nil)
55
- if readonly
56
- define_singleton_method(key) do
57
- self.send(:_convert_string_to_typeof_value, type, default, separator: separator)
58
- end
59
- else
60
- define_singleton_method(key) do
61
- val = self.send(:_value_of, key)
62
- result = nil
63
- if !val.nil?
64
- result = val
65
- else
66
- result = default
67
- result = default.call if default.is_a?(Proc)
68
- end
69
-
70
- result = self.send(:_convert_string_to_typeof_value, type, result, separator: separator)
71
-
72
- result
64
+ def _define_field(key, default: nil, type: :string, readonly: false, separator: nil)
65
+ @defined_fields ||= []
66
+ @defined_fields << {
67
+ key: key.to_s,
68
+ default: default,
69
+ type: type || :string,
70
+ readonly: readonly.nil? ? false : readonly
71
+ }
72
+
73
+ if readonly
74
+ define_singleton_method(key) do
75
+ send(:_convert_string_to_typeof_value, type, default, separator: separator)
76
+ end
77
+ else
78
+ define_singleton_method(key) do
79
+ val = send(:_value_of, key)
80
+ result = nil
81
+ if !val.nil?
82
+ result = val
83
+ else
84
+ result = default
85
+ result = default.call if default.is_a?(Proc)
73
86
  end
74
87
 
75
- define_singleton_method("#{key}=") do |value|
76
- var_name = key.to_s
88
+ result = send(:_convert_string_to_typeof_value, type, result, separator: separator)
77
89
 
78
- record = find_by(var: var_name) || new(var: var_name)
79
- value = self.send(:_convert_string_to_typeof_value, type, value, separator: separator)
90
+ result
91
+ end
80
92
 
81
- record.value = value
82
- record.save!
93
+ define_singleton_method("#{key}=") do |value|
94
+ var_name = key.to_s
83
95
 
84
- value
85
- end
86
- end
96
+ record = find_by(var: var_name) || new(var: var_name)
97
+ value = send(:_convert_string_to_typeof_value, type, value, separator: separator)
87
98
 
88
- if type == :boolean
89
- define_singleton_method("#{key}?") do
90
- self.send(key)
91
- end
92
- end
93
- end
99
+ record.value = value
100
+ record.save!
94
101
 
95
- def _convert_string_to_typeof_value(type, value, separator: nil)
96
- return value unless [String, Integer, Float, BigDecimal].include?(value.class)
97
-
98
- case type
99
- when :boolean
100
- value == "true" || value == "1" || value == 1 || value == true
101
- when :array
102
- value.split(separator || SEPARATOR_REGEXP).reject { |str| str.empty? }.map(&:strip)
103
- when :hash
104
- value = YAML.load(value).to_h rescue eval(value).to_h rescue {}
105
- value.deep_stringify_keys!
106
- value
107
- when :integer
108
- value.to_i
109
- when :float
110
- value.to_f
111
- when :big_decimal
112
- value.to_d
113
- else
114
102
  value
115
103
  end
116
104
  end
117
105
 
118
- def _value_of(var_name)
119
- raise "#{self.table_name} does not exist." unless table_exists?
106
+ if type == :boolean
107
+ define_singleton_method("#{key}?") do
108
+ send(key)
109
+ end
110
+ end
111
+ end
120
112
 
121
- _all_settings[var_name.to_s]
113
+ def _convert_string_to_typeof_value(type, value, separator: nil)
114
+ return value unless [String, Integer, Float, BigDecimal].include?(value.class)
115
+
116
+ case type
117
+ when :boolean
118
+ value == "true" || value == "1" || value == 1 || value == true
119
+ when :array
120
+ value.split(separator || SEPARATOR_REGEXP).reject { |str| str.empty? }.map(&:strip)
121
+ when :hash
122
+ value = begin
123
+ begin
124
+ YAML.load(value).to_h
125
+ rescue StandardError
126
+ eval(value).to_h
127
+ end
128
+ rescue StandardError
129
+ {}
130
+ end
131
+ value.deep_stringify_keys!
132
+ ActiveSupport::HashWithIndifferentAccess.new(value)
133
+ when :integer
134
+ value.to_i
135
+ when :float
136
+ value.to_f
137
+ when :big_decimal
138
+ value.to_d
139
+ else
140
+ value
122
141
  end
142
+ end
123
143
 
124
- def rails_initialized?
125
- Rails.application && Rails.application.initialized?
144
+ def _value_of(var_name)
145
+ unless _table_exists?
146
+ # Fallback to default value if table was not ready (before migrate)
147
+ puts "WARNING: table: \"#{table_name}\" does not exist or not database connection, `#{name}.#{var_name}` fallback to returns the default value."
148
+ return nil
126
149
  end
127
150
 
128
- def _all_settings
129
- raise "You cannot use settings before Rails initialize." unless rails_initialized?
130
- RequestStore.store[:rails_settings_all_settings] ||= begin
131
- Rails.cache.fetch(self.cache_key, expires_in: 1.week) do
132
- vars = unscoped.select("var, value")
133
- result = {}
134
- vars.each { |record| result[record.var] = record.value }
135
- result.with_indifferent_access
136
- end
151
+ _all_settings[var_name.to_s]
152
+ end
153
+
154
+ def _table_exists?
155
+ table_exists?
156
+ rescue => e
157
+ false
158
+ end
159
+
160
+ def rails_initialized?
161
+ Rails.application&.initialized?
162
+ end
163
+
164
+ def _all_settings
165
+ RequestStore.store[:rails_settings_all_settings] ||= begin
166
+ Rails.cache.fetch(cache_key, expires_in: 1.week) do
167
+ vars = unscoped.select("var, value")
168
+ result = {}
169
+ vars.each { |record| result[record.var] = record.value }
170
+ result.with_indifferent_access
137
171
  end
138
172
  end
173
+ end
139
174
  end
140
175
  end
141
176
  end
@@ -3,7 +3,7 @@
3
3
  module RailsSettings
4
4
  class << self
5
5
  def version
6
- "2.2.1"
6
+ "2.3.5"
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.2.1
4
+ version: 2.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Lee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-14 00:00:00.000000000 Z
11
+ date: 2020-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pg
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rubocop
71
85
  requirement: !ruby/object:Gem::Requirement