rails-settings-cached 0.5.6 → 0.7.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 +5 -5
- data/README.md +284 -202
- data/lib/generators/settings/install_generator.rb +12 -3
- data/lib/generators/settings/templates/app.yml +13 -0
- data/lib/generators/settings/templates/migration.rb +1 -1
- data/lib/generators/settings/templates/model.rb +5 -1
- data/lib/rails-settings/base.rb +22 -90
- data/lib/rails-settings/default.rb +40 -0
- data/lib/rails-settings/extend.rb +2 -2
- data/lib/rails-settings/railtie.rb +8 -0
- data/lib/rails-settings/scoped_settings.rb +1 -1
- data/lib/rails-settings/settings.rb +115 -5
- data/lib/rails-settings/version.rb +1 -1
- data/lib/rails-settings-cached.rb +3 -8
- metadata +77 -5
- data/lib/rails-settings/cached_settings.rb +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ac720065903da7de8fed10d171d0145ddeabb6b7d7f0a1b6c66f7e497c79ddb1
|
4
|
+
data.tar.gz: 2b20fdde2d824978ef981935b88faf7e3773469bacaa7520dcbcf59376bf0d76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eab7e6fb1eb995cf1d4e548812964ca6ac342e47c2792598f3db835b6611c31b13dd89e8d0973cf545799dbfeb8aa5ef5bed307a0559ee82484a37ff4df01ceb
|
7
|
+
data.tar.gz: 67139f1e6fea2edc490f43fa7a782a245a1b40b82ece38e4bcb479e18752511f2420131add354a48f5140ebf7130bf1ba8af6349336fa483d6e809625f80a7a6
|
data/README.md
CHANGED
@@ -1,202 +1,284 @@
|
|
1
|
-
# Settings
|
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.
|
9
|
-
|
10
|
-
## Status
|
11
|
-
|
12
|
-
[](https://rubygems.org/gems/rails-settings-cached) [,
|
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.
|
9
|
+
|
10
|
+
## Status
|
11
|
+
|
12
|
+
[](https://rubygems.org/gems/rails-settings-cached) [](http://travis-ci.org/huacnlee/rails-settings-cached) [](https://codeclimate.com/github/huacnlee/rails-settings-cached) [](https://codecov.io/github/huacnlee/rails-settings-cached?branch=master)
|
13
|
+
|
14
|
+
## Setup
|
15
|
+
|
16
|
+
Edit your Gemfile:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
gem "rails-settings-cached"
|
20
|
+
```
|
21
|
+
|
22
|
+
Generate your settings:
|
23
|
+
|
24
|
+
```bash
|
25
|
+
$ rails g settings:install
|
26
|
+
```
|
27
|
+
|
28
|
+
If you want custom model name:
|
29
|
+
|
30
|
+
```bash
|
31
|
+
$ rails g settings:install
|
32
|
+
```
|
33
|
+
|
34
|
+
Or use a custom name:
|
35
|
+
|
36
|
+
```bash
|
37
|
+
$ rails g settings:install SiteConfig
|
38
|
+
```
|
39
|
+
|
40
|
+
You will get `app/models/setting.rb`
|
41
|
+
|
42
|
+
```rb
|
43
|
+
class Setting < RailsSettings::Base
|
44
|
+
source Rails.root.join("config/app.yml")
|
45
|
+
# cache_prefix { "v1" }
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
Now just put that migration in the database with:
|
50
|
+
|
51
|
+
```bash
|
52
|
+
rake db:migrate
|
53
|
+
```
|
54
|
+
|
55
|
+
## Usage
|
56
|
+
|
57
|
+
The syntax is easy. First, lets create some settings to keep track of:
|
58
|
+
|
59
|
+
```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' }
|
65
|
+
```
|
66
|
+
|
67
|
+
Now lets read them back:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
Setting.foo # returns 123
|
71
|
+
```
|
72
|
+
|
73
|
+
Changing an existing setting is the same as creating a new setting:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
Setting.foo = 'super duper bar'
|
77
|
+
```
|
78
|
+
|
79
|
+
Decide you dont want to track a particular setting anymore?
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
Setting.destroy :foo
|
83
|
+
Setting.foo # returns nil
|
84
|
+
```
|
85
|
+
|
86
|
+
Want a list of all the settings?
|
87
|
+
```ruby
|
88
|
+
Setting.get_all
|
89
|
+
```
|
90
|
+
|
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:
|
92
|
+
|
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 }
|
102
|
+
```
|
103
|
+
|
104
|
+
## Extend a model
|
105
|
+
|
106
|
+
Settings may be bound to any existing ActiveRecord object. Define this association like this:
|
107
|
+
Notice! is not do caching in this version.
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
class User < ActiveRecord::Base
|
111
|
+
include RailsSettings::Extend
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
Then you can set/get a setting for a given user instance just by doing this:
|
116
|
+
|
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 }
|
123
|
+
```
|
124
|
+
|
125
|
+
If you want to find users having or not having some settings, there are named scopes for this:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
User.with_settings
|
129
|
+
# => returns a scope of users having any setting
|
130
|
+
|
131
|
+
User.with_settings_for('color')
|
132
|
+
# => returns a scope of users having a 'color' setting
|
133
|
+
|
134
|
+
User.without_settings
|
135
|
+
# returns a scope of users having no setting at all (means user.settings.get_all == {})
|
136
|
+
|
137
|
+
User.without_settings('color')
|
138
|
+
# returns a scope of users having no 'color' setting (means user.settings.color == nil)
|
139
|
+
```
|
140
|
+
|
141
|
+
## Default settings
|
142
|
+
|
143
|
+
Sometimes you may want define default settings.
|
144
|
+
|
145
|
+
RailsSettings has generate a config YAML file in:
|
146
|
+
|
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"
|
154
|
+
|
155
|
+
development:
|
156
|
+
<<: *defaults
|
157
|
+
|
158
|
+
test:
|
159
|
+
<<: *defaults
|
160
|
+
|
161
|
+
production:
|
162
|
+
<<: *defaults
|
163
|
+
```
|
164
|
+
|
165
|
+
And you can use by `Setting` model:
|
166
|
+
|
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
|
+
```
|
178
|
+
|
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.
|
181
|
+
|
182
|
+
### Caching flow:
|
183
|
+
|
184
|
+
```
|
185
|
+
Setting.foo -> Check Cache -> Exist - Write Cache -> Return
|
186
|
+
|
|
187
|
+
Check DB -> Exist -> Write Cache -> Return
|
188
|
+
|
|
189
|
+
Check Default -> Exist -> Write Cache -> Return
|
190
|
+
|
|
191
|
+
Return nil
|
192
|
+
```
|
193
|
+
|
194
|
+
## Change cache key
|
195
|
+
|
196
|
+
When `config/app.yml` has changed, you may need change the cache prefix to expires caches.
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
class Setting < RailsSettings::Base
|
200
|
+
cache_prefix { 'you-prefix' }
|
201
|
+
...
|
202
|
+
end
|
203
|
+
```
|
204
|
+
|
205
|
+
-----
|
206
|
+
|
207
|
+
## How to create a list, form to manage Settings?
|
208
|
+
|
209
|
+
If you want create an admin interface to editing the Settings, you can try methods in follow:
|
210
|
+
|
211
|
+
config/routes.rb
|
212
|
+
|
213
|
+
```rb
|
214
|
+
namespace :admin do
|
215
|
+
resources :settings
|
216
|
+
end
|
217
|
+
```
|
218
|
+
|
219
|
+
|
220
|
+
app/controllers/admin/settings_controller.rb
|
221
|
+
|
222
|
+
```rb
|
223
|
+
module Admin
|
224
|
+
class SettingsController < ApplicationController
|
225
|
+
before_action :get_setting, only: [:edit, :update]
|
226
|
+
|
227
|
+
def index
|
228
|
+
@settings = Setting.get_all
|
229
|
+
end
|
230
|
+
|
231
|
+
def edit
|
232
|
+
end
|
233
|
+
|
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
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def get_setting
|
245
|
+
@setting = Setting.find_by(var: params[:id]) || Setting.new(var: params[:id])
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
```
|
250
|
+
|
251
|
+
app/views/admin/settings/index.html.erb
|
252
|
+
|
253
|
+
```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>
|
264
|
+
<% end %>
|
265
|
+
</table>
|
266
|
+
```
|
267
|
+
|
268
|
+
app/views/admin/settings/edit.html.erb
|
269
|
+
|
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 %>
|
275
|
+
<% end %>
|
276
|
+
```
|
277
|
+
|
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).
|
281
|
+
|
282
|
+
## Use case:
|
283
|
+
|
284
|
+
- [ruby-china/ruby-china](https://github.com/ruby-china/ruby-china)
|
@@ -3,7 +3,7 @@ require 'rails/generators/migration'
|
|
3
3
|
|
4
4
|
module Settings
|
5
5
|
class InstallGenerator < Rails::Generators::NamedBase
|
6
|
-
desc
|
6
|
+
desc 'Generate RailsSettings files.'
|
7
7
|
include Rails::Generators::Migration
|
8
8
|
|
9
9
|
argument :name, type: :string, default: 'setting'
|
@@ -26,8 +26,17 @@ module Settings
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def install_setting
|
29
|
-
template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
30
|
-
|
29
|
+
template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
30
|
+
template 'app.yml', File.join('config', 'app.yml')
|
31
|
+
migration_template 'migration.rb', 'db/migrate/create_settings.rb', migration_version: migration_version
|
32
|
+
end
|
33
|
+
|
34
|
+
def rails5?
|
35
|
+
Rails.version.start_with? '5'
|
36
|
+
end
|
37
|
+
|
38
|
+
def migration_version
|
39
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if rails5?
|
31
40
|
end
|
32
41
|
end
|
33
42
|
end
|
@@ -1,3 +1,7 @@
|
|
1
1
|
# RailsSettings Model
|
2
|
-
class <%= class_name %> < RailsSettings::
|
2
|
+
class <%= class_name %> < RailsSettings::Base
|
3
|
+
source Rails.root.join("config/app.yml")
|
4
|
+
|
5
|
+
# When config/app.yml has changed, you need change this prefix to v2, v3 ... to expires caches
|
6
|
+
# cache_prefix { "v1" }
|
3
7
|
end
|
data/lib/rails-settings/base.rb
CHANGED
@@ -1,112 +1,44 @@
|
|
1
1
|
module RailsSettings
|
2
|
-
class Base <
|
3
|
-
|
4
|
-
|
5
|
-
class SettingNotFound < RuntimeError; end
|
6
|
-
|
7
|
-
cattr_accessor :defaults
|
8
|
-
@@defaults = {}.with_indifferent_access
|
9
|
-
|
10
|
-
belongs_to :thing, polymorphic: true
|
11
|
-
|
12
|
-
# Support old plugin
|
13
|
-
if defined?(SettingsDefaults::DEFAULTS)
|
14
|
-
@@defaults = SettingsDefaults::DEFAULTS.with_indifferent_access
|
2
|
+
class Base < Settings
|
3
|
+
def rewrite_cache
|
4
|
+
Rails.cache.write(cache_key, value)
|
15
5
|
end
|
16
6
|
|
17
|
-
|
18
|
-
|
19
|
-
YAML.load(self[:value]) if self[:value].present?
|
7
|
+
def expire_cache
|
8
|
+
Rails.cache.delete(cache_key)
|
20
9
|
end
|
21
10
|
|
22
|
-
|
23
|
-
|
24
|
-
self[:value] = new_value.to_yaml
|
11
|
+
def cache_key
|
12
|
+
self.class.cache_key(var, thing)
|
25
13
|
end
|
26
14
|
|
27
15
|
class << self
|
28
|
-
|
29
|
-
|
30
|
-
method_name = method.to_s
|
31
|
-
super(method, *args)
|
32
|
-
rescue NoMethodError
|
33
|
-
# set a value for a variable
|
34
|
-
if method_name[-1] == '='
|
35
|
-
var_name = method_name.sub('=', '')
|
36
|
-
value = args.first
|
37
|
-
self[var_name] = value
|
38
|
-
else
|
39
|
-
# retrieve a value
|
40
|
-
self[method_name]
|
41
|
-
end
|
16
|
+
def cache_prefix(&block)
|
17
|
+
@cache_prefix = block
|
42
18
|
end
|
43
19
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
obj.destroy
|
51
|
-
true
|
20
|
+
def cache_key(var_name, scope_object)
|
21
|
+
scope = ["rails_settings_cached"]
|
22
|
+
scope << @cache_prefix.call if @cache_prefix
|
23
|
+
scope << "#{scope_object.class.name}-#{scope_object.id}" if scope_object
|
24
|
+
scope << var_name.to_s
|
25
|
+
scope.join('/')
|
52
26
|
end
|
53
27
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
result = {}
|
60
|
-
vars.each do |record|
|
61
|
-
result[record.var] = record.value
|
28
|
+
def [](key)
|
29
|
+
return super(key) unless rails_initialized?
|
30
|
+
val = Rails.cache.fetch(cache_key(key, @object)) do
|
31
|
+
super(key)
|
62
32
|
end
|
63
|
-
|
64
|
-
default_keys = default_keys.select {|k| k.start_with? starting_with } if starting_with
|
65
|
-
result.merge! @@defaults.slice(*(default_keys - result.keys))
|
66
|
-
|
67
|
-
result.with_indifferent_access
|
68
|
-
end
|
69
|
-
|
70
|
-
def where(sql = nil)
|
71
|
-
vars = thing_scoped.where(sql) if sql
|
72
|
-
vars
|
73
|
-
end
|
74
|
-
|
75
|
-
# get a setting value by [] notation
|
76
|
-
def [](var_name)
|
77
|
-
object(var_name).try(:value) || @@defaults[var_name.to_s]
|
33
|
+
val
|
78
34
|
end
|
79
35
|
|
80
36
|
# set a setting value by [] notation
|
81
37
|
def []=(var_name, value)
|
82
|
-
|
83
|
-
|
84
|
-
record = object(var_name) || thing_scoped.new(var: var_name)
|
85
|
-
record.value = value
|
86
|
-
record.save!
|
87
|
-
|
38
|
+
super
|
39
|
+
Rails.cache.write(cache_key(var_name, @object), value)
|
88
40
|
value
|
89
41
|
end
|
90
|
-
|
91
|
-
def merge!(var_name, hash_value)
|
92
|
-
raise ArgumentError unless hash_value.is_a?(Hash)
|
93
|
-
|
94
|
-
old_value = self[var_name] || {}
|
95
|
-
raise TypeError, "Existing value is not a hash, can't merge!" unless old_value.is_a?(Hash)
|
96
|
-
|
97
|
-
new_value = old_value.merge(hash_value)
|
98
|
-
self[var_name] = new_value if new_value != old_value
|
99
|
-
|
100
|
-
new_value
|
101
|
-
end
|
102
|
-
|
103
|
-
def object(var_name)
|
104
|
-
thing_scoped.where(var: var_name.to_s).first
|
105
|
-
end
|
106
|
-
|
107
|
-
def thing_scoped
|
108
|
-
unscoped.where('thing_type is NULL and thing_id is NULL')
|
109
|
-
end
|
110
42
|
end
|
111
43
|
end
|
112
44
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module RailsSettings
|
4
|
+
class Default < ::Hash
|
5
|
+
class MissingKey < StandardError; end
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def enabled?
|
9
|
+
source_path && File.exist?(source_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def source(value = nil)
|
13
|
+
@source ||= value
|
14
|
+
end
|
15
|
+
|
16
|
+
def source_path
|
17
|
+
@source || Rails.root.join('config/app.yml')
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](key)
|
21
|
+
# foo.bar.dar Nested fetch value
|
22
|
+
return instance[key] if instance.key?(key)
|
23
|
+
keys = key.to_s.split('.')
|
24
|
+
instance.dig(*keys)
|
25
|
+
end
|
26
|
+
|
27
|
+
def instance
|
28
|
+
return @instance if defined? @instance
|
29
|
+
@instance = new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
content = open(self.class.source_path).read
|
35
|
+
hash = content.empty? ? {} : YAML.load(ERB.new(content).result).to_hash
|
36
|
+
hash = hash[Rails.env] || {}
|
37
|
+
replace hash
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -9,7 +9,7 @@ module RailsSettings
|
|
9
9
|
.select("DISTINCT #{table_name}.*")
|
10
10
|
}
|
11
11
|
|
12
|
-
scope :with_settings_for, lambda
|
12
|
+
scope :with_settings_for, lambda { |var|
|
13
13
|
joins("JOIN settings ON (settings.thing_id = #{table_name}.#{primary_key} AND
|
14
14
|
settings.thing_type = '#{base_class.name}') AND settings.var = '#{var}'")
|
15
15
|
}
|
@@ -20,7 +20,7 @@ module RailsSettings
|
|
20
20
|
.where('settings.id IS NULL')
|
21
21
|
}
|
22
22
|
|
23
|
-
scope :without_settings_for, lambda
|
23
|
+
scope :without_settings_for, lambda { |var|
|
24
24
|
where('settings.id IS NULL')
|
25
25
|
.joins("LEFT JOIN settings ON (settings.thing_id = #{table_name}.#{primary_key} AND
|
26
26
|
settings.thing_type = '#{base_class.name}') AND settings.var = '#{var}'")
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module RailsSettings
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
initializer 'rails_settings.active_record.initialization' do
|
4
|
+
RailsSettings::Base.after_commit :rewrite_cache, on: %i(create update)
|
5
|
+
RailsSettings::Base.after_commit :expire_cache, on: %i(destroy)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
@@ -1,9 +1,119 @@
|
|
1
1
|
module RailsSettings
|
2
|
-
class Settings < Base
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
class Settings < ActiveRecord::Base
|
3
|
+
self.table_name = table_name_prefix + 'settings'
|
4
|
+
|
5
|
+
class SettingNotFound < RuntimeError; end
|
6
|
+
|
7
|
+
belongs_to :thing, polymorphic: true
|
8
|
+
|
9
|
+
# get the value field, YAML decoded
|
10
|
+
def value
|
11
|
+
YAML.load(self[:value]) if self[:value].present?
|
12
|
+
end
|
13
|
+
|
14
|
+
# set the value field, YAML encoded
|
15
|
+
def value=(new_value)
|
16
|
+
self[:value] = new_value.to_yaml
|
17
|
+
end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
# get or set a variable with the variable as the called method
|
21
|
+
# rubocop:disable Style/MethodMissing
|
22
|
+
def method_missing(method, *args)
|
23
|
+
method_name = method.to_s
|
24
|
+
super(method, *args)
|
25
|
+
rescue NoMethodError
|
26
|
+
# set a value for a variable
|
27
|
+
if method_name[-1] == '='
|
28
|
+
var_name = method_name.sub('=', '')
|
29
|
+
value = args.first
|
30
|
+
self[var_name] = value
|
31
|
+
else
|
32
|
+
# retrieve a value
|
33
|
+
self[method_name]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# destroy the specified settings record
|
38
|
+
def destroy(var_name)
|
39
|
+
var_name = var_name.to_s
|
40
|
+
obj = object(var_name)
|
41
|
+
raise SettingNotFound, "Setting variable \"#{var_name}\" not found" if obj.nil?
|
42
|
+
|
43
|
+
obj.destroy
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
# retrieve all settings as a hash (optionally starting with a given namespace)
|
48
|
+
def get_all(starting_with = nil)
|
49
|
+
vars = thing_scoped.select('var, value')
|
50
|
+
vars = vars.where("var LIKE '#{starting_with}%'") if starting_with
|
51
|
+
result = {}
|
52
|
+
vars.each { |record| result[record.var] = record.value }
|
53
|
+
result.reverse_merge!(default_settings(starting_with))
|
54
|
+
result.with_indifferent_access
|
55
|
+
end
|
56
|
+
|
57
|
+
def where(sql = nil)
|
58
|
+
vars = thing_scoped.where(sql) if sql
|
59
|
+
vars
|
60
|
+
end
|
61
|
+
|
62
|
+
# get a setting value by [] notation
|
63
|
+
def [](var_name)
|
64
|
+
val = object(var_name)
|
65
|
+
return val.value if val
|
66
|
+
return Default[var_name] if Default.enabled?
|
67
|
+
end
|
68
|
+
|
69
|
+
# set a setting value by [] notation
|
70
|
+
def []=(var_name, value)
|
71
|
+
var_name = var_name.to_s
|
72
|
+
|
73
|
+
record = object(var_name) || thing_scoped.new(var: var_name)
|
74
|
+
record.value = value
|
75
|
+
record.save!
|
76
|
+
|
77
|
+
value
|
78
|
+
end
|
79
|
+
|
80
|
+
def merge!(var_name, hash_value)
|
81
|
+
raise ArgumentError unless hash_value.is_a?(Hash)
|
82
|
+
|
83
|
+
old_value = self[var_name] || {}
|
84
|
+
raise TypeError, "Existing value is not a hash, can't merge!" unless old_value.is_a?(Hash)
|
85
|
+
|
86
|
+
new_value = old_value.merge(hash_value)
|
87
|
+
self[var_name] = new_value if new_value != old_value
|
88
|
+
|
89
|
+
new_value
|
90
|
+
end
|
91
|
+
|
92
|
+
def object(var_name)
|
93
|
+
return nil unless rails_initialized?
|
94
|
+
return nil unless table_exists?
|
95
|
+
thing_scoped.where(var: var_name.to_s).first
|
96
|
+
end
|
97
|
+
|
98
|
+
def thing_scoped
|
99
|
+
unscoped.where('thing_type is NULL and thing_id is NULL')
|
100
|
+
end
|
101
|
+
|
102
|
+
def source(filename)
|
103
|
+
Default.source(filename)
|
104
|
+
end
|
105
|
+
|
106
|
+
def rails_initialized?
|
107
|
+
Rails.application && Rails.application.initialized?
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def default_settings(starting_with = nil)
|
113
|
+
return {} unless Default.enabled?
|
114
|
+
return Default.instance if starting_with.nil?
|
115
|
+
Default.instance.select { |key, _| key.to_s.start_with?(starting_with) }
|
116
|
+
end
|
7
117
|
end
|
8
118
|
end
|
9
119
|
end
|
@@ -1,15 +1,10 @@
|
|
1
|
-
require_relative 'rails-settings/base'
|
2
1
|
require_relative 'rails-settings/settings'
|
3
|
-
require_relative 'rails-settings/
|
2
|
+
require_relative 'rails-settings/base'
|
4
3
|
require_relative 'rails-settings/scoped_settings'
|
4
|
+
require_relative 'rails-settings/default'
|
5
5
|
require_relative 'rails-settings/extend'
|
6
|
+
require_relative 'rails-settings/railtie'
|
6
7
|
require_relative 'rails-settings/version'
|
7
8
|
|
8
9
|
module RailsSettings
|
9
|
-
class Railtie < Rails::Railtie
|
10
|
-
initializer "rails_settings.active_record.initialization" do
|
11
|
-
RailsSettings::CachedSettings.after_commit :rewrite_cache, on: %i(create update)
|
12
|
-
RailsSettings::CachedSettings.after_commit :expire_cache, on: %i(destroy)
|
13
|
-
end
|
14
|
-
end
|
15
10
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-settings-cached
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Lee
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2018-06-13 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rails
|
@@ -27,6 +27,76 @@ dependencies:
|
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 4.2.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: sqlite3
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
type: :development
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: rubocop
|
46
|
+
requirement: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - '='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 0.46.0
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - '='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.46.0
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: simplecov
|
60
|
+
requirement: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: rspec
|
74
|
+
requirement: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
name: codecov
|
88
|
+
requirement: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
type: :development
|
94
|
+
prerelease: false
|
95
|
+
version_requirements: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
30
100
|
description: "\n This is improved from rails-settings, added caching.\n Settings
|
31
101
|
plugin for Rails that makes managing a table of global key,\n value pairs easy.
|
32
102
|
Think of it like a global Hash stored in you database,\n that uses simple ActiveRecord
|
@@ -40,12 +110,14 @@ extra_rdoc_files: []
|
|
40
110
|
files:
|
41
111
|
- README.md
|
42
112
|
- lib/generators/settings/install_generator.rb
|
113
|
+
- lib/generators/settings/templates/app.yml
|
43
114
|
- lib/generators/settings/templates/migration.rb
|
44
115
|
- lib/generators/settings/templates/model.rb
|
45
116
|
- lib/rails-settings-cached.rb
|
46
117
|
- lib/rails-settings/base.rb
|
47
|
-
- lib/rails-settings/
|
118
|
+
- lib/rails-settings/default.rb
|
48
119
|
- lib/rails-settings/extend.rb
|
120
|
+
- lib/rails-settings/railtie.rb
|
49
121
|
- lib/rails-settings/scoped_settings.rb
|
50
122
|
- lib/rails-settings/settings.rb
|
51
123
|
- lib/rails-settings/version.rb
|
@@ -60,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
60
132
|
requirements:
|
61
133
|
- - ">="
|
62
134
|
- !ruby/object:Gem::Version
|
63
|
-
version: '2.
|
135
|
+
version: '2.3'
|
64
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
137
|
requirements:
|
66
138
|
- - ">="
|
@@ -68,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
140
|
version: '0'
|
69
141
|
requirements: []
|
70
142
|
rubyforge_project:
|
71
|
-
rubygems_version: 2.6
|
143
|
+
rubygems_version: 2.7.6
|
72
144
|
signing_key:
|
73
145
|
specification_version: 4
|
74
146
|
summary: Settings plugin for Rails that makes managing a table of global keys.
|
@@ -1,54 +0,0 @@
|
|
1
|
-
module RailsSettings
|
2
|
-
class CachedSettings < Base
|
3
|
-
def rewrite_cache
|
4
|
-
Rails.cache.write(cache_key, value)
|
5
|
-
end
|
6
|
-
|
7
|
-
def expire_cache
|
8
|
-
Rails.cache.delete(cache_key)
|
9
|
-
end
|
10
|
-
|
11
|
-
def cache_key
|
12
|
-
self.class.cache_key(var, thing)
|
13
|
-
end
|
14
|
-
|
15
|
-
class << self
|
16
|
-
def cache_prefix(&block)
|
17
|
-
@cache_prefix = block
|
18
|
-
end
|
19
|
-
|
20
|
-
def cache_key(var_name, scope_object)
|
21
|
-
scope = "rails_settings_cached:"
|
22
|
-
scope << "#{@cache_prefix.call}:" if @cache_prefix
|
23
|
-
scope << "#{scope_object.class.name}-#{scope_object.id}:" if scope_object
|
24
|
-
scope << "#{var_name}"
|
25
|
-
end
|
26
|
-
|
27
|
-
def [](var_name)
|
28
|
-
value = Rails.cache.fetch(cache_key(var_name, @object)) do
|
29
|
-
super(var_name)
|
30
|
-
end
|
31
|
-
|
32
|
-
if value.nil?
|
33
|
-
@@defaults[var_name.to_s] if value.nil?
|
34
|
-
else
|
35
|
-
value
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# set a setting value by [] notation
|
40
|
-
def []=(var_name, value)
|
41
|
-
super
|
42
|
-
|
43
|
-
Rails.cache.write(cache_key(var_name, @object),value)
|
44
|
-
|
45
|
-
value
|
46
|
-
end
|
47
|
-
|
48
|
-
def save_default(key, value)
|
49
|
-
return false unless self[key].nil?
|
50
|
-
self[key] = value
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|