rails-settings-cached 2.0.2 → 2.2.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: 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.