rails-settings-cached 2.0.2 → 2.2.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: 2f5d17c59cd0c8b1c7c587169c32a7b7003c9067086a7b43e40d716973c8b104
4
- data.tar.gz: 9e4b276543867580abcfa9da999fe3e81303459df28db49c76f2e75bef6679e7
3
+ metadata.gz: 765057576ddcdb19d9f394f1844950f03e8c70944abd9b104e70824f60f7e0e5
4
+ data.tar.gz: 0d2a2c4aa7560d96bee3a0c1a0d50f7cb89bffd5c650ae47f2bd6169c0d12b6e
5
5
  SHA512:
6
- metadata.gz: 4be5e67948d944b2daa60c574586e297b638fc17e828a4923dc010ad691402b69bd8b06c823b228a3eaedafbd00fc2796d43c7986cb34a3bc0e5ae401eae8647
7
- data.tar.gz: 7021a6b8d97b31f3f28557f51bef405cf5cfba5ed2194ee50d1b56ce599e1ca1aa288498d39c3ceefadd0618781610bd12344cf468b826ee4b7125fc640ce267
6
+ metadata.gz: 908f7ae3d8e01710f9df4cb32a77b2302129107bcd34254cb5237fc5f5b98f2e4007fe315751ab3fd7e2212e14a0db133f796f994b0bd6a1cee48768717a01a9
7
+ data.tar.gz: fe611e7af4ac5ca72a98040c63b0475833878ac6f11b82953fd80458bb6b96311fff7fc174f890171f466f724be809cd334bc184b0cb0c8c7b3ae94f5fbee28f
@@ -1,5 +1,4 @@
1
- Copyright (c) 2006 Alex Wayne
2
- Some additional features added 2009 by Georg Ledermann
1
+ Copyright (c) 2019 Jason Lee
3
2
 
4
3
  Permission is hereby granted, free of charge, to any person obtaining
5
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,14 +1,15 @@
1
1
  ## Rails Settings Cached
2
2
 
3
3
  This a plugin that makes managing a table of
4
- global key, value pairs easy. Think of it like a global Hash stored in your database,
4
+ а global key, value pairs easy. Think of it like a global Hash stored in your database,
5
5
  that uses simple ActiveRecord like methods for manipulation. Keep track of any global
6
- setting that you dont want to hard code into your rails app. You can store any kind
6
+ setting that you don't want to hard code into your rails app. You can store any kind
7
7
  of object. Strings, numbers, arrays, or any object.
8
8
 
9
9
  > 🚨 BREAK CHANGES WARNING:
10
- > rails-settings-cached 2.x has redesign the API, the new version will compatible with the stored setting values by older version.
11
- > When you wants to upgrade 2.x, you must read the README again, and follow guides to change your Setting model.
10
+ > rails-settings-cached 2.x has redesigned the API, the new version will compatible with the stored setting values by an older version.
11
+ > When you want to upgrade 2.x, you must read the README again, and follow guides to change your Setting model.
12
+ > 0.x stable branch: https://github.com/huacnlee/rails-settings-cached/tree/0.x
12
13
 
13
14
  ## Status
14
15
 
@@ -19,7 +20,7 @@ of object. Strings, numbers, arrays, or any object.
19
20
  Edit your Gemfile:
20
21
 
21
22
  ```ruby
22
- gem "rails-settings-cached"
23
+ gem "rails-settings-cached", "~> 2.0"
23
24
  ```
24
25
 
25
26
  Generate your settings:
@@ -49,7 +50,10 @@ class Setting < RailsSettings::Base
49
50
  field :host, default: "http://example.com"
50
51
  field :readonly_item, type: :integer, default: 100, readonly: true
51
52
  field :user_limits, type: :integer, default: 20
53
+ field :exchange_rate, type: :float, default: 0.123
52
54
  field :admin_emails, type: :array, default: %w[admin@rubyonrails.org]
55
+ # Override array separator, default: /[\n,]/ split with \n or comma.
56
+ field :tips, type: :array, separator: /[\n]+/
53
57
  field :captcha_enable, type: :boolean, default: 1
54
58
  field :notification_options, type: :hash, default: {
55
59
  send_all: true,
@@ -59,7 +63,7 @@ class Setting < RailsSettings::Base
59
63
  end
60
64
  ```
61
65
 
62
- You must use `field` method to statement the setting keys, otherwice you can't use it.
66
+ You must use `field` method to statement the setting keys, otherwise you can't use it.
63
67
 
64
68
  Now just put that migration in the database with:
65
69
 
@@ -69,7 +73,7 @@ rake db:migrate
69
73
 
70
74
  ## Usage
71
75
 
72
- The syntax is easy. First, lets create some settings to keep track of:
76
+ The syntax is easy. First, let's create some settings to keep track of:
73
77
 
74
78
  ```ruby
75
79
  irb > Setting.host
@@ -132,7 +136,7 @@ irb > Setting.notification_options
132
136
 
133
137
  ## Readonly field
134
138
 
135
- Some times you may need use Setting before Rails initialize, for example `config/devise.rb`
139
+ Sometimes you may need to use Setting before Rails is initialized, for example `config/devise.rb`
136
140
 
137
141
  ```rb
138
142
  Devise.setup do |config|
@@ -162,9 +166,9 @@ Setting.host -> Check Cache -> Exist - Get value of key for cache -> Return
162
166
  Return default value or nil
163
167
  ```
164
168
 
165
- In each Setting keys call, we will load the cache/db and save in Thread.current for avoid hit cache/db.
169
+ In each Setting keys call, we will load the cache/db and save in [RequestStore](https://github.com/steveklabnik/request_store) to avoid hit cache/db.
166
170
 
167
- Each key update will expires the cache, so do not add some frequent update key.
171
+ Each key update will expire the cache, so do not add some frequent update key.
168
172
 
169
173
  ## Change cache key
170
174
 
@@ -189,9 +193,9 @@ end
189
193
 
190
194
  -----
191
195
 
192
- ## How to manage Settings in admin interface?
196
+ ## How to manage Settings in the admin interface?
193
197
 
194
- If you want create an admin interface to editing the Settings, you can try methods in follow:
198
+ If you want to create an admin interface to editing the Settings, you can try methods in following:
195
199
 
196
200
  config/routes.rb
197
201
 
@@ -209,18 +213,13 @@ module Admin
209
213
  class SettingsController < ApplicationController
210
214
  before_action :get_setting, only: [:edit, :update]
211
215
 
212
- def show
213
- end
214
-
215
216
  def create
216
217
  setting_params.keys.each do |key|
217
- next if key.to_s == "site_logo"
218
218
  Setting.send("#{key}=", setting_params[key].strip) unless setting_params[key].nil?
219
219
  end
220
- redirect_to admin_settings_path(notice: "Setting was successfully updated.")
220
+ redirect_to settings_path, notice: "Setting was successfully updated."
221
221
  end
222
222
 
223
-
224
223
  private
225
224
  def setting_params
226
225
  params.require(:setting).permit(:host, :user_limits, :admin_emails,
@@ -256,10 +255,80 @@ app/views/admin/settings/show.html.erb
256
255
  <%= f.text_area :notification_options, value: YAML.dump(Setting.notification_options), class: "form-control", style: "height: 180px;" %>
257
256
  <div class="form-text">
258
257
  Use YAML format to config the SMTP_html
259
- </details>
258
+ </div>
259
+ </div>
260
260
  <% end %>
261
261
  ```
262
262
 
263
- ## Use case:
263
+ ## Backward compatible to support 0.x scoped settings
264
+
265
+ You may used the scoped setting feature in 0.x version. Before you upgrade rails-settings-cached 2.x, you must follow this guide to backward compatible it.
266
+
267
+ For example:
268
+
269
+ ```rb
270
+ class User < ApplicationRecord
271
+ include RailsSettings::Extend
272
+ end
273
+
274
+ @user.settings.color = "red"
275
+ @user.settings.foo = 123
276
+ ```
277
+
278
+ create `app/models/concerns/scoped_setting.rb`
279
+
280
+ ```rb
281
+ module ScopedSetting
282
+ extend ActiveSupport::Concern
283
+
284
+ included do
285
+ has_many :settings, as: :thing
286
+ end
287
+
288
+ class_methods do
289
+ def scoped_field(name, default: nil)
290
+ define_method(name) do
291
+ obj = settings.where(var: name).take || settings.new(var: name, value: default)
292
+ obj.value
293
+ end
294
+
295
+ define_method("#{name}=") do |val|
296
+ record = settings.where(var: name).take || settings.new(var: name)
297
+ record.value = val
298
+ record.save!
299
+
300
+ val
301
+ end
302
+ end
303
+ end
304
+ end
305
+ ```
306
+
307
+ Now include it for your model:
308
+
309
+ ```rb
310
+ class User < ApplicationRecord
311
+ include ScopedSetting
312
+
313
+ scoped_field :color, default: ""
314
+ scoped_field :foo, default: 0
315
+ end
316
+ ```
317
+
318
+ Now you must to find project with ".setting." for replace with:
319
+
320
+ Same values will fetch from the `settings` table.
321
+
322
+ ```rb
323
+ @user.color = "red"
324
+ @user.color # => "red"
325
+ @user.foo = 123
326
+ @user.foo # =>
327
+ ```
328
+
329
+ ## Use cases:
264
330
 
265
- - [ruby-china/ruby-china](https://github.com/ruby-china/ruby-china)
331
+ - [ruby-china/homeland](https://github.com/ruby-china/homeland)
332
+ - [thebluedoc/bluedoc](https://github.com/thebluedoc/bluedoc/blob/master/app/models/setting.rb)
333
+ - [tootsuite/mastodon](https://github.com/tootsuite/mastodon)
334
+ - [helpyio/helpy](https://github.com/helpyio/helpy)
@@ -32,12 +32,16 @@ module Settings
32
32
  migration_template "migration.rb", "db/migrate/create_settings.rb", migration_version: migration_version
33
33
  end
34
34
 
35
- def rails5?
36
- Rails.version.start_with? "5"
35
+ def rails_version_major
36
+ Rails::VERSION::MAJOR
37
+ end
38
+
39
+ def rails_version_minor
40
+ Rails::VERSION::MINOR
37
41
  end
38
42
 
39
43
  def migration_version
40
- "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if rails5?
44
+ "[#{rails_version_major}.#{rails_version_minor}]" if rails_version_major >= 5
41
45
  end
42
46
  end
43
47
  end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "request_store"
4
+
3
5
  module RailsSettings
4
6
  class Base < ActiveRecord::Base
5
7
  class SettingNotFound < RuntimeError; end
6
8
 
7
- SEPARATOR_REGEXP = /[\s,]/
9
+ SEPARATOR_REGEXP = /[\n,;]+/
8
10
  self.table_name = table_name_prefix + "settings"
9
11
 
10
12
  # get the value field, YAML decoded
@@ -23,12 +25,14 @@ module RailsSettings
23
25
 
24
26
  class << self
25
27
  def clear_cache
26
- Thread.current[:rails_settings_all_settings] = nil
28
+ RequestStore.store[:rails_settings_all_settings] = nil
27
29
  Rails.cache.delete(self.cache_key)
28
30
  end
29
31
 
30
32
  def field(key, **opts)
31
- _define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly])
33
+ @keys ||= []
34
+ @keys << key.to_s
35
+ _define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly], separator: opts[:separator])
32
36
  end
33
37
 
34
38
  def cache_prefix(&block)
@@ -41,14 +45,19 @@ module RailsSettings
41
45
  scope.join("/")
42
46
  end
43
47
 
48
+ def keys
49
+ @keys
50
+ end
51
+
44
52
  private
45
- def _define_field(key, default: nil, type: :string, readonly: false)
53
+
54
+ def _define_field(key, default: nil, type: :string, readonly: false, separator: nil)
46
55
  if readonly
47
- self.class.define_method(key) do
48
- self.send(:_covert_string_to_typeof_value, type, default)
56
+ define_singleton_method(key) do
57
+ self.send(:_convert_string_to_typeof_value, type, default, separator: separator)
49
58
  end
50
59
  else
51
- self.class.define_method(key) do
60
+ define_singleton_method(key) do
52
61
  val = self.send(:_value_of, key)
53
62
  result = nil
54
63
  if !val.nil?
@@ -58,16 +67,16 @@ module RailsSettings
58
67
  result = default.call if default.is_a?(Proc)
59
68
  end
60
69
 
61
- result = self.send(:_covert_string_to_typeof_value, type, result)
70
+ result = self.send(:_convert_string_to_typeof_value, type, result, separator: separator)
62
71
 
63
72
  result
64
73
  end
65
74
 
66
- self.class.define_method("#{key}=") do |value|
75
+ define_singleton_method("#{key}=") do |value|
67
76
  var_name = key.to_s
68
77
 
69
78
  record = find_by(var: var_name) || new(var: var_name)
70
- value = self.send(:_covert_string_to_typeof_value, type, value)
79
+ value = self.send(:_convert_string_to_typeof_value, type, value, separator: separator)
71
80
 
72
81
  record.value = value
73
82
  record.save!
@@ -77,26 +86,30 @@ module RailsSettings
77
86
  end
78
87
 
79
88
  if type == :boolean
80
- self.class.define_method("#{key}?") do
89
+ define_singleton_method("#{key}?") do
81
90
  self.send(key)
82
91
  end
83
92
  end
84
93
  end
85
94
 
86
- def _covert_string_to_typeof_value(type, value)
87
- return value unless value.is_a?(String) || value.is_a?(Integer)
95
+ def _convert_string_to_typeof_value(type, value, separator: nil)
96
+ return value unless [String, Integer, Float, BigDecimal].include?(value.class)
88
97
 
89
98
  case type
90
99
  when :boolean
91
- return value == "true" || value == "1" || value == 1 || value == true
100
+ value == "true" || value == "1" || value == 1 || value == true
92
101
  when :array
93
- return value.split(SEPARATOR_REGEXP).reject { |str| str.empty? }
102
+ value.split(separator || SEPARATOR_REGEXP).reject { |str| str.empty? }.map(&:strip)
94
103
  when :hash
95
- value = YAML.load(value).to_hash rescue {}
104
+ value = YAML.load(value).to_h rescue eval(value).to_h rescue {}
96
105
  value.deep_stringify_keys!
97
- return value
106
+ value
98
107
  when :integer
99
- return value.to_i
108
+ value.to_i
109
+ when :float
110
+ value.to_f
111
+ when :big_decimal
112
+ value.to_d
100
113
  else
101
114
  value
102
115
  end
@@ -113,8 +126,8 @@ module RailsSettings
113
126
  end
114
127
 
115
128
  def _all_settings
116
- raise "You can use settings before Rails initialize." unless rails_initialized?
117
- Thread.current[:rails_settings_all_settings] ||= begin
129
+ raise "You cannot use settings before Rails initialize." unless rails_initialized?
130
+ RequestStore.store[:rails_settings_all_settings] ||= begin
118
131
  Rails.cache.fetch(self.cache_key, expires_in: 1.week) do
119
132
  vars = unscoped.select("var, value")
120
133
  result = {}
@@ -3,7 +3,7 @@
3
3
  module RailsSettings
4
4
  class << self
5
5
  def version
6
- "2.0.2"
6
+ "2.2.0"
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.0.2
4
+ version: 2.2.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: 2019-04-26 00:00:00.000000000 Z
11
+ date: 2020-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -25,7 +25,21 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 4.2.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: sqlite3
28
+ name: request_store
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: codecov
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
@@ -39,7 +53,7 @@ dependencies:
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
- name: rubocop
56
+ name: minitest
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - ">="
@@ -53,7 +67,7 @@ dependencies:
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
- name: simplecov
70
+ name: rubocop
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
@@ -67,7 +81,7 @@ dependencies:
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
- name: minitest
84
+ name: simplecov
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
@@ -81,7 +95,7 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
- name: codecov
98
+ name: sqlite3
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
@@ -133,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
147
  - !ruby/object:Gem::Version
134
148
  version: '0'
135
149
  requirements: []
136
- rubygems_version: 3.0.1
150
+ rubygems_version: 3.0.3
137
151
  signing_key:
138
152
  specification_version: 4
139
153
  summary: Settings plugin for Rails that makes managing a table of global keys.