rails-settings-cached 2.2.1 → 2.3.5

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