rails-settings-cached 0.7.2 → 2.7.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: eba484df56932a47956229096367746c7ffdeb979c61e2f9bcadbad09c0fd0a6
4
- data.tar.gz: 73ce168eead5d2627323f5944d2c7ee8629c85df602e3b432afdcb05ee29247a
3
+ metadata.gz: d45081eacc51de459cd0bc48469430474cd561386e924b40996bd5f66c1299e5
4
+ data.tar.gz: 485e2df525a6d3b66dfed0c0b5935aa8134b13ae0b0528d1fae536e5b19e4ae2
5
5
  SHA512:
6
- metadata.gz: 26f409db40e28e6febeba959cc27a127d6caa531d66974792efc7f1e4cf7ee8d0ca1e21130d6c874937ed645b24929e44094fd351add876f5471c0f37bf4a28d
7
- data.tar.gz: 02d122fcc7346aac33f12cf470462bb283602d277cd2fc09c1cba40c4d597ccd4e65527572e7ebd523535c7fe92bcf948a99ead45f1f3f6dd7420ba95703d2b0
6
+ metadata.gz: 6651da35fec5737f76192ec01f0980ea45a85c69efb768c22edbce29b490f29dfa2498798b5af6d45a126955a3fe72bf2fa1ae76bd249237b83f408f7bba72c4
7
+ data.tar.gz: b96670e501b9c5aff237b02fd2da2560b654dd2835322b2e64e28679e3edf646ee940f2f2ffe69bfa7d851732ac4844bb47b01e292f4ef4b5f04e587977f8c21
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2019 Jason Lee
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND
17
+ NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,284 +1,454 @@
1
1
  # Rails Settings Cached
2
2
 
3
- This is improved from [rails-settings](https://github.com/ledermann/rails-settings),
4
- added caching for all settings. Settings is a plugin that makes managing a table of
5
- global key, value pairs easy. Think of it like a global Hash stored in your database,
6
- that uses simple ActiveRecord like methods for manipulation. Keep track of any global
7
- setting that you dont want to hard code into your rails app. You can store any kind
8
- of object. Strings, numbers, arrays, or any object.
3
+ The best solution for store global settings in Rails applications.
9
4
 
10
- ## Status
5
+ This gem will make managing a table of а global key, value pairs easy. Think of it like a global Hash stored in your database, that uses simple ActiveRecord like methods for manipulation. Keep track of any global setting that you don't want to hard code into your rails app.
11
6
 
12
- [![Gem Version](https://badge.fury.io/rb/rails-settings-cached.svg)](https://rubygems.org/gems/rails-settings-cached) [![CI Status](https://travis-ci.org/huacnlee/rails-settings-cached.svg)](http://travis-ci.org/huacnlee/rails-settings-cached) [![Code Climate](https://codeclimate.com/github/huacnlee/rails-settings-cached/badges/gpa.svg)](https://codeclimate.com/github/huacnlee/rails-settings-cached) [![codecov.io](https://codecov.io/github/huacnlee/rails-settings-cached/coverage.svg?branch=master)](https://codecov.io/github/huacnlee/rails-settings-cached?branch=master)
7
+ You can store any kind of object. Strings, numbers, arrays, booleans, or any object.
13
8
 
14
- ## Setup
9
+ [![Gem Version](https://badge.fury.io/rb/rails-settings-cached.svg)](https://rubygems.org/gems/rails-settings-cached) [![build](https://github.com/huacnlee/rails-settings-cached/workflows/build/badge.svg)](https://github.com/huacnlee/rails-settings-cached/actions?query=workflow%3Abuild) [![codecov.io](https://codecov.io/github/huacnlee/rails-settings-cached/coverage.svg?branch=master)](https://codecov.io/github/huacnlee/rails-settings-cached?branch=master)
15
10
 
16
- Edit your Gemfile:
17
-
18
- ```ruby
19
- gem "rails-settings-cached"
20
- ```
11
+ ## Installation
21
12
 
22
- Generate your settings:
13
+ Edit your Gemfile:
23
14
 
24
15
  ```bash
25
- $ rails g settings:install
16
+ $ bundle add rails-settings-cached
26
17
  ```
27
18
 
28
- If you want custom model name:
19
+ Generate your settings:
29
20
 
30
21
  ```bash
31
22
  $ rails g settings:install
32
- ```
33
23
 
34
- Or use a custom name:
35
-
36
- ```bash
37
- $ rails g settings:install SiteConfig
24
+ # Or use a custom name:
25
+ $ rails g settings:install AppConfig
38
26
  ```
39
27
 
40
28
  You will get `app/models/setting.rb`
41
29
 
42
30
  ```rb
43
31
  class Setting < RailsSettings::Base
44
- source Rails.root.join("config/app.yml")
45
32
  # cache_prefix { "v1" }
33
+
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]
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, group: :limits
50
+ end
51
+
52
+ field :notification_options, type: :hash, default: {
53
+ send_all: true,
54
+ logging: true,
55
+ sender_email: "foo@bar.com"
56
+ }, group: :advanced
57
+
58
+ field :readonly_item, type: :integer, default: 100, readonly: true
46
59
  end
47
60
  ```
48
61
 
62
+ You must use the `field` method to statement the setting keys, otherwise you can't use it.
63
+
49
64
  Now just put that migration in the database with:
50
65
 
51
66
  ```bash
52
- rake db:migrate
67
+ $ rails db:migrate
53
68
  ```
54
69
 
55
70
  ## Usage
56
71
 
57
- The syntax is easy. First, lets create some settings to keep track of:
72
+ The syntax is easy. First, let's create some settings to keep track of:
58
73
 
59
74
  ```ruby
60
- Setting.admin_password = 'supersecret'
61
- Setting.date_format = '%m %d, %Y'
62
- Setting.cocktails = ['Martini', 'Screwdriver', 'White Russian']
63
- Setting.foo = 123
64
- Setting.credentials = { :username => 'tom', :password => 'secret' }
75
+ irb > Setting.host
76
+ "http://example.com"
77
+ irb > Setting.app_name
78
+ "Rails Settings"
79
+ irb > Setting.app_name = "Rails Settings Cached"
80
+ irb > Setting.app_name
81
+ "Rails Settings Cached"
82
+
83
+ irb > Setting.user_limits
84
+ 20
85
+ irb > Setting.user_limits = "30"
86
+ irb > Setting.user_limits
87
+ 30
88
+ irb > Setting.user_limits = 45
89
+ irb > Setting.user_limits
90
+ 45
91
+
92
+ irb > Setting.captcha_enable
93
+ 1
94
+ irb > Setting.captcha_enable?
95
+ true
96
+ irb > Setting.captcha_enable = "0"
97
+ irb > Setting.captcha_enable
98
+ false
99
+ irb > Setting.captcha_enable = "1"
100
+ irb > Setting.captcha_enable
101
+ true
102
+ irb > Setting.captcha_enable = "false"
103
+ irb > Setting.captcha_enable
104
+ false
105
+ irb > Setting.captcha_enable = "true"
106
+ irb > Setting.captcha_enable
107
+ true
108
+ irb > Setting.captcha_enable?
109
+ true
110
+
111
+ irb > Setting.admin_emails
112
+ ["admin@rubyonrails.org"]
113
+ irb > Setting.admin_emails = %w[foo@bar.com bar@dar.com]
114
+ irb > Setting.admin_emails
115
+ ["foo@bar.com", "bar@dar.com"]
116
+ irb > Setting.admin_emails = "huacnlee@gmail.com,admin@admin.com\nadmin@rubyonrails.org"
117
+ irb > Setting.admin_emails
118
+ ["huacnlee@gmail.com", "admin@admin.com", "admin@rubyonrails.org"]
119
+
120
+ irb > Setting.notification_options
121
+ {
122
+ send_all: true,
123
+ logging: true,
124
+ sender_email: "foo@bar.com"
125
+ }
126
+ irb > Setting.notification_options = {
127
+ sender_email: "notice@rubyonrails.org"
128
+ }
129
+ irb > Setting.notification_options
130
+ {
131
+ sender_email: "notice@rubyonrails.org"
132
+ }
65
133
  ```
66
134
 
67
- Now lets read them back:
135
+ ### Get defined fields
68
136
 
69
- ```ruby
70
- Setting.foo # returns 123
71
- ```
137
+ > version 2.3+
72
138
 
73
- Changing an existing setting is the same as creating a new setting:
74
-
75
- ```ruby
76
- Setting.foo = 'super duper bar'
139
+ ```rb
140
+ # Get all keys
141
+ Setting.keys
142
+ => ["app_name", "host", "default_locale", "readonly_item"]
143
+
144
+ # Get editable keys
145
+ Settng.editable_keys
146
+ => ["app_name", "default_locale"]
147
+
148
+ # Get readonly keys
149
+ Setting.readonly_keys
150
+ => ["host", "readonly_item"]
151
+
152
+ # Get options of field
153
+ Setting.get_field("host")
154
+ => { scope: :application, key: "host", type: :string, default: "http://example.com", readonly: true }
155
+ Setting.get_field("app_name")
156
+ => { scope: :application, key: "app_name", type: :string, default: "Rails Settings", readonly: false }
157
+ Setting.get_field(:user_limits)
158
+ => { scope: :limits, key: "user_limits", type: :integer, default: 20, readonly: false }
77
159
  ```
78
160
 
79
- Decide you dont want to track a particular setting anymore?
80
-
81
- ```ruby
82
- Setting.destroy :foo
83
- Setting.foo # returns nil
84
- ```
161
+ #### Get All defined fields
85
162
 
86
- Want a list of all the settings?
87
- ```ruby
88
- Setting.get_all
89
- ```
163
+ > version 2.7.0+
90
164
 
91
- You need name spaces and want a list of settings for a give name space? Just choose your prefered named space delimiter and use `Setting.get_all` (`Settings.all` for # Rails 3.x and 4.0.x) like this:
165
+ You can use `defined_fields` method to get all defined fields in Setting.
92
166
 
93
- ```ruby
94
- Setting['preferences.color'] = :blue
95
- Setting['preferences.size'] = :large
96
- Setting['license.key'] = 'ABC-DEF'
97
- # Rails 4.1.x
98
- Setting.get_all('preferences.')
99
- # Rails 3.x and 4.0.x
100
- Setting.all('preferences.')
101
- # returns { 'preferences.color' => :blue, 'preferences.size' => :large }
167
+ ```rb
168
+ # Get editable fields and group by scope
169
+ editable_fields = Setting.defined_fields
170
+ .select { |field| !field[:readonly] }
171
+ .group_by { |field| field[:scope] }
102
172
  ```
103
173
 
104
- ## Extend a model
174
+ ## Validations
105
175
 
106
- Settings may be bound to any existing ActiveRecord object. Define this association like this:
107
- Notice! is not do caching in this version.
176
+ You can use `validates` options to special the [Rails Validation](https://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates) for fields.
108
177
 
109
- ```ruby
110
- class User < ActiveRecord::Base
111
- include RailsSettings::Extend
178
+ ```rb
179
+ class Setting < RailsSettings::Base
180
+ # cache_prefix { "v1" }
181
+ field :app_name, default: "Rails Settings", validates: { presence: true, length: { in: 2..20 } }
182
+ field :default_locale, default: "zh-CN", validates: { presence: true, inclusion: { in: %w[zh-CN en jp], message: "is not included in [zh-CN, en, jp]" } }
112
183
  end
113
184
  ```
114
185
 
115
- Then you can set/get a setting for a given user instance just by doing this:
186
+ Now validate will work on record save:
116
187
 
117
- ```ruby
118
- user = User.find(123)
119
- user.settings.color = :red
120
- user.settings.color # returns :red
121
- user.settings.get_all
122
- # { "color" => :red }
188
+ ```rb
189
+ irb> Setting.app_name = ""
190
+ ActiveRecord::RecordInvalid: (Validation failed: App name can't be blank)
191
+ irb> Setting.app_name = "Rails Settings"
192
+ "Rails Settings"
193
+ irb> Setting.default_locale = "zh-TW"
194
+ ActiveRecord::RecordInvalid: (Validation failed: Default locale is not included in [zh-CN, en, jp])
195
+ irb> Setting.default_locale = "en"
196
+ "en"
123
197
  ```
124
198
 
125
- If you want to find users having or not having some settings, there are named scopes for this:
199
+ Validate by `save` / `valid?` method:
126
200
 
127
- ```ruby
128
- User.with_settings
129
- # => returns a scope of users having any setting
201
+ ```rb
130
202
 
131
- User.with_settings_for('color')
132
- # => returns a scope of users having a 'color' setting
203
+ setting = Setting.find_or_initialize_by(var: :app_name)
204
+ setting.value = ""
205
+ setting.valid?
206
+ # => false
207
+ setting.errors.full_messages
208
+ # => ["App name can't be blank", "App name too short (minimum is 2 characters)"]
209
+
210
+ setting = Setting.find_or_initialize_by(var: :default_locale)
211
+ setting.value = "zh-TW"
212
+ setting.save
213
+ # => false
214
+ setting.errors.full_messages
215
+ # => ["Default locale is not included in [zh-CN, en, jp]"]
216
+ setting.value = "en"
217
+ setting.valid?
218
+ # => true
219
+ ```
133
220
 
134
- User.without_settings
135
- # returns a scope of users having no setting at all (means user.settings.get_all == {})
221
+ ## Use Setting in Rails initializing:
136
222
 
137
- User.without_settings('color')
138
- # returns a scope of users having no 'color' setting (means user.settings.color == nil)
223
+ In `version 2.3+` you can use Setting before Rails is initialized.
224
+
225
+ For example `config/initializers/devise.rb`
226
+
227
+ ```rb
228
+ Devise.setup do |config|
229
+ if Setting.omniauth_google_client_id.present?
230
+ config.omniauth :google_oauth2, Setting.omniauth_google_client_id, Setting.omniauth_google_client_secret
231
+ end
232
+ end
139
233
  ```
140
234
 
141
- ## Default settings
235
+ ```rb
236
+ class Setting < RailsSettings::Base
237
+ field :omniauth_google_client_id, default: ENV["OMNIAUTH_GOOGLE_CLIENT_ID"]
238
+ field :omniauth_google_client_secret, default: ENV["OMNIAUTH_GOOGLE_CLIENT_SECRET"]
239
+ end
240
+ ```
142
241
 
143
- Sometimes you may want define default settings.
242
+ ## Readonly field
144
243
 
145
- RailsSettings has generate a config YAML file in:
244
+ You may also want use Setting before Rails initialize:
146
245
 
147
- ```yml
148
- # config/app.yml
149
- defaults: &defaults
150
- github_token: "123456"
151
- twitter_token: "<%= ENV["TWITTER_TOKEN"] %>"
152
- foo:
153
- bar: "Foo bar"
246
+ ```
247
+ config/environments/*.rb
248
+ ```
154
249
 
155
- development:
156
- <<: *defaults
250
+ If you want do that do that, the setting field must has `readonly: true`.
157
251
 
158
- test:
159
- <<: *defaults
252
+ For example:
160
253
 
161
- production:
162
- <<: *defaults
254
+ ```rb
255
+ class Setting < RailsSettings::Base
256
+ field :mailer_provider, default: (ENV["mailer_provider"] || "smtp"), readonly: true
257
+ field :mailer_options, type: :hash, readonly: true, default: {
258
+ address: ENV["mailer_options.address"],
259
+ port: ENV["mailer_options.port"],
260
+ domain: ENV["mailer_options.domain"],
261
+ user_name: ENV["mailer_options.user_name"],
262
+ password: ENV["mailer_options.password"],
263
+ authentication: ENV["mailer_options.authentication"] || "login",
264
+ enable_starttls_auto: ENV["mailer_options.enable_starttls_auto"]
265
+ }
266
+ end
163
267
  ```
164
268
 
165
- And you can use by `Setting` model:
269
+ config/environments/production.rb
166
270
 
167
- ```
168
- Setting.github_token
169
- => "123456"
170
- Setting.github_token = "654321"
171
- # Save into database.
172
- Setting.github_token
173
- # Read from databae / caching.
174
- => "654321"
175
- Setting['foo.bar']
176
- => 'Foo bar'
177
- ```
271
+ ```rb
272
+ # You must require_relative directly in Rails 6.1+ in config/environments/production.rb
273
+ require_relative "../../app/models/setting"
178
274
 
179
- NOTE: YAML setting it also under the cache scope, when you restart Rails application, cache will expire,
180
- so when you want change default config, you need restart Rails application server.
275
+ Rails.application.configure do
276
+ config.action_mailer.delivery_method = :smtp
277
+ config.action_mailer.smtp_settings = Setting.mailer_options.deep_symbolize_keys
278
+ end
279
+ ```
181
280
 
182
- ### Caching flow:
281
+ ## Caching flow:
183
282
 
184
283
  ```
185
- Setting.foo -> Check Cache -> Exist - Write Cache -> Return
186
- |
187
- Check DB -> Exist -> Write Cache -> Return
284
+ Setting.host -> Check Cache -> Exist - Get value of key for cache -> Return
188
285
  |
189
- Check Default -> Exist -> Write Cache -> Return
286
+ Fetch all key and values from DB -> Write Cache -> Get value of key for cache -> return
190
287
  |
191
- Return nil
288
+ Return default value or nil
192
289
  ```
193
290
 
291
+ In each Setting keys call, we will load the cache/db and save in [ActiveSupport::CurrentAttributes](https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html) to avoid hit cache/db.
292
+
293
+ Each key update will expire the cache, so do not add some frequent update key.
294
+
194
295
  ## Change cache key
195
296
 
196
- When `config/app.yml` has changed, you may need change the cache prefix to expires caches.
297
+ Some times you may need to force update cache, now you can use `cache_prefix`
197
298
 
198
299
  ```ruby
199
300
  class Setting < RailsSettings::Base
200
- cache_prefix { 'you-prefix' }
301
+ cache_prefix { "you-prefix" }
201
302
  ...
202
303
  end
203
304
  ```
204
305
 
205
- -----
306
+ In testing, you need add `Setting.clear_cache` for each Test case:
307
+
308
+ ```rb
309
+ class ActiveSupport::TestCase
310
+ teardown do
311
+ Setting.clear_cache
312
+ end
313
+ end
314
+ ```
315
+
316
+ ---
206
317
 
207
- ## How to create a list, form to manage Settings?
318
+ ## How to manage Settings in the admin interface?
208
319
 
209
- If you want create an admin interface to editing the Settings, you can try methods in follow:
320
+ If you want to create an admin interface to editing the Settings, you can try methods in following:
210
321
 
211
322
  config/routes.rb
212
323
 
213
324
  ```rb
214
325
  namespace :admin do
215
- resources :settings
326
+ resource :settings
216
327
  end
217
328
  ```
218
329
 
219
-
220
330
  app/controllers/admin/settings_controller.rb
221
331
 
222
332
  ```rb
223
333
  module Admin
224
334
  class SettingsController < ApplicationController
225
- before_action :get_setting, only: [:edit, :update]
226
-
227
- def index
228
- @settings = Setting.get_all
229
- end
335
+ def create
336
+ @errors = ActiveModel::Errors.new
337
+ setting_params.keys.each do |key|
338
+ next if setting_params[key].nil?
339
+
340
+ setting = Setting.new(var: key)
341
+ setting.value = setting_params[key].strip
342
+ unless setting.valid?
343
+ @errors.merge!(setting.errors)
344
+ end
345
+ end
230
346
 
231
- def edit
232
- end
347
+ if @errors.any?
348
+ render :new
349
+ end
233
350
 
234
- def update
235
- if @setting.value != params[:setting][:value]
236
- @setting.value = params[:setting][:value]
237
- @setting.save
238
- redirect_to admin_settings_path, notice: 'Setting has updated.'
239
- else
240
- redirect_to admin_settings_path
351
+ setting_params.keys.each do |key|
352
+ Setting.send("#{key}=", setting_params[key].strip) unless setting_params[key].nil?
241
353
  end
242
- end
243
354
 
244
- def get_setting
245
- @setting = Setting.find_by(var: params[:id]) || Setting.new(var: params[:id])
355
+ redirect_to admin_settings_path, notice: "Setting was successfully updated."
246
356
  end
357
+
358
+ private
359
+ def setting_params
360
+ params.require(:setting).permit(:host, :user_limits, :admin_emails,
361
+ :captcha_enable, :notification_options)
362
+ end
247
363
  end
248
364
  end
249
365
  ```
250
366
 
251
- app/views/admin/settings/index.html.erb
367
+ app/views/admin/settings/show.html.erb
252
368
 
253
369
  ```erb
254
- <table>
255
- <tr>
256
- <th>Key</th>
257
- <th></th>
258
- </tr>
259
- <% @settings.each_key do |key| %>
260
- <tr>
261
- <td><%= key %></td>
262
- <td><%= link_to 'edit', edit_admin_setting_path(key) %></td>
263
- </tr>
370
+ <%= form_for(Setting.new, url: admin_settings_path) do |f| %>
371
+ <% if @errors.any? %>
372
+ <div class="alert alert-block alert-danger">
373
+ <ul>
374
+ <% @errors.full_messages.each do |msg| %>
375
+ <li><%= msg %></li>
376
+ <% end %>
377
+ </ul>
378
+ </div>
264
379
  <% end %>
265
- </table>
266
- ```
267
-
268
- app/views/admin/settings/edit.html.erb
269
380
 
270
- ```erb
271
- <%= form_for(@setting, url: admin_setting_path(@setting.var), method: 'patch') do |f| %>
272
- <label><%= @setting.var %></label>
273
- <%= f.text_area :value, rows: 10 %>
274
- <%= f.submit %>
381
+ <div class="form-group">
382
+ <label class="control-label">Host</label>
383
+ <%= f.text_field :host, value: Setting.host, class: "form-control", placeholder: "http://localhost" %>
384
+ </div>
385
+
386
+ <div class="form-group form-checkbox">
387
+ <label>
388
+ <%= f.check_box :captcha_enable, checked: Setting.captcha_enable? %>
389
+ Enable/Disable Captcha
390
+ </label>
391
+ </div>
392
+
393
+ <div class="form-group">
394
+ <label class="control-label">Admin Emails</label>
395
+ <%= f.text_area :admin_emails, value: Setting.admin_emails.join("\n"), class: "form-control" %>
396
+ </div>
397
+
398
+ <div class="form-group">
399
+ <label class="control-label">Notification options</label>
400
+ <%= f.text_area :notification_options, value: YAML.dump(Setting.notification_options), class: "form-control", style: "height: 180px;" %>
401
+ <div class="form-text">
402
+ Use YAML format to config the SMTP_html
403
+ </div>
404
+ </div>
405
+
406
+ <div>
407
+ <%= f.submit 'Update Settings' %>
408
+ </div>
275
409
  <% end %>
276
410
  ```
277
411
 
278
- Also you may use [rails-settings-ui](https://github.com/accessd/rails-settings-ui) gem
279
- for building ready to using interface with validations,
280
- or [activeadmin_settings_cached](https://github.com/artofhuman/activeadmin_settings_cached) gem if you use [activeadmin](https://github.com/activeadmin/activeadmin).
412
+ ## Scoped Settings
281
413
 
282
- ## Use case:
414
+ > 🚨 BREAK CHANGES WARNING:
415
+ > rails-settings-cached 2.x has redesigned the API, the new version will compatible with the stored setting values by an older version.
416
+ > When you want to upgrade 2.x, you must read the README again, and follow guides to change your Setting model.
417
+ > 0.x stable branch: https://github.com/huacnlee/rails-settings-cached/tree/0.x
418
+
419
+ - [Backward compatible to support 0.x scoped settings](docs/backward-compatible-to-scoped-settings.md)
420
+
421
+ For new project / new user of rails-settings-cached. The [ActiveRecord::AttributeMethods::Serialization](https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html#method-i-serialize) is best choice.
422
+
423
+ > This is reason of why rails-settings-cached 2.x removed **Scoped Settings** feature.
424
+
425
+ For example:
426
+
427
+ We wants a preferences setting for user.
428
+
429
+ ```rb
430
+ class User < ActiveRecord::Base
431
+ serialize :preferences
432
+ end
433
+
434
+ @user = User.new
435
+ @user.preferences[:receive_emails] = true
436
+ @user.preferences[:public_email] = true
437
+ @user.save
438
+ ```
283
439
 
284
- - [ruby-china/ruby-china](https://github.com/ruby-china/ruby-china)
440
+ ## Use cases:
441
+
442
+ - [ruby-china/homeland](https://github.com/ruby-china/homeland) - master
443
+ - [forem/forem](https://github.com/forem/forem) - 2.x
444
+ - [siwapp/siwapp](https://github.com/siwapp/siwapp) - 2.x
445
+ - [aidewoode/black_candy](https://github.com/aidewoode/black_candy) - 2.x
446
+ - [huacnlee/bluedoc](https://github.com/huacnlee/bluedoc) - 2.x
447
+ - [getzealot/zealot](https://github.com/getzealot/zealot) - 2.x
448
+ - [kaishuu0123/rebacklogs](https://github.com/kaishuu0123/rebacklogs) - 2.x
449
+ - [texterify/texterify](https://github.com/texterify/texterify) - 2.x
450
+ - [tootsuite/mastodon](https://github.com/tootsuite/mastodon) - 0.6.x
451
+ - [helpyio/helpy](https://github.com/helpyio/helpy) - 0.5.x
452
+ - [daqing/rabel](https://github.com/daqing/rabel) - 0.4.x
453
+
454
+ And more than [1K repositories](https://github.com/huacnlee/rails-settings-cached/network/dependents) used.