rails-settings-cached 0.5.6 → 0.6.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 +4 -4
- data/README.md +263 -202
- data/lib/generators/settings/install_generator.rb +2 -1
- data/lib/generators/settings/templates/app.yml +13 -0
- data/lib/generators/settings/templates/model.rb +2 -0
- data/lib/rails-settings-cached.rb +4 -3
- data/lib/rails-settings/base.rb +29 -85
- data/lib/rails-settings/cached_settings.rb +4 -49
- data/lib/rails-settings/default.rb +43 -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
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa6d7bd1e608d80ee9995d8f1393e9fce6a19d2f
|
4
|
+
data.tar.gz: d47dd443d8e1afe1ea8dde4e7e10acbff1aafd3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0101c4f85fec7b475e5306bc94882c39ce7711f66b3cdc5c5175aedc333a138503388ba56d4dee0d956bb8ce2af396c030e04fcee89ef8d75749fc932e8259dd
|
7
|
+
data.tar.gz: 892a9665b231016b4c2ea079afdd94a01895169795ca1637cc23e7a2bf007823b5400d37fef0d400a2ca40204618d5dbe2c2a6b391fa7f4b53dee59db91b7373
|
data/README.md
CHANGED
@@ -1,202 +1,263 @@
|
|
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) [](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
|
20
|
-
```
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
```
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
Setting.
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
Setting.
|
86
|
-
|
87
|
-
```
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
```
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
```
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
1
|
+
# Rails Settings Cached
|
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) [](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 SiteConfig
|
32
|
+
```
|
33
|
+
|
34
|
+
Now just put that migration in the database with:
|
35
|
+
|
36
|
+
```bash
|
37
|
+
rake db:migrate
|
38
|
+
```
|
39
|
+
|
40
|
+
## Usage
|
41
|
+
|
42
|
+
The syntax is easy. First, lets create some settings to keep track of:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
Setting.admin_password = 'supersecret'
|
46
|
+
Setting.date_format = '%m %d, %Y'
|
47
|
+
Setting.cocktails = ['Martini', 'Screwdriver', 'White Russian']
|
48
|
+
Setting.foo = 123
|
49
|
+
Setting.credentials = { :username => 'tom', :password => 'secret' }
|
50
|
+
```
|
51
|
+
|
52
|
+
Now lets read them back:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
Setting.foo # returns 123
|
56
|
+
```
|
57
|
+
|
58
|
+
Changing an existing setting is the same as creating a new setting:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
Setting.foo = 'super duper bar'
|
62
|
+
```
|
63
|
+
|
64
|
+
Decide you dont want to track a particular setting anymore?
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
Setting.destroy :foo
|
68
|
+
Setting.foo # returns nil
|
69
|
+
```
|
70
|
+
|
71
|
+
Want a list of all the settings?
|
72
|
+
```ruby
|
73
|
+
Setting.get_all
|
74
|
+
```
|
75
|
+
|
76
|
+
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:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
Setting['preferences.color'] = :blue
|
80
|
+
Setting['preferences.size'] = :large
|
81
|
+
Setting['license.key'] = 'ABC-DEF'
|
82
|
+
# Rails 4.1.x
|
83
|
+
Setting.get_all('preferences.')
|
84
|
+
# Rails 3.x and 4.0.x
|
85
|
+
Setting.all('preferences.')
|
86
|
+
# returns { 'preferences.color' => :blue, 'preferences.size' => :large }
|
87
|
+
```
|
88
|
+
|
89
|
+
## Extend a model
|
90
|
+
|
91
|
+
Settings may be bound to any existing ActiveRecord object. Define this association like this:
|
92
|
+
Notice! is not do caching in this version.
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
class User < ActiveRecord::Base
|
96
|
+
include RailsSettings::Extend
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
Then you can set/get a setting for a given user instance just by doing this:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
user = User.find(123)
|
104
|
+
user.settings.color = :red
|
105
|
+
user.settings.color # returns :red
|
106
|
+
user.settings.get_all
|
107
|
+
# { "color" => :red }
|
108
|
+
```
|
109
|
+
|
110
|
+
If you want to find users having or not having some settings, there are named scopes for this:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
User.with_settings
|
114
|
+
# => returns a scope of users having any setting
|
115
|
+
|
116
|
+
User.with_settings_for('color')
|
117
|
+
# => returns a scope of users having a 'color' setting
|
118
|
+
|
119
|
+
User.without_settings
|
120
|
+
# returns a scope of users having no setting at all (means user.settings.get_all == {})
|
121
|
+
|
122
|
+
User.without_settings('color')
|
123
|
+
# returns a scope of users having no 'color' setting (means user.settings.color == nil)
|
124
|
+
```
|
125
|
+
|
126
|
+
## Default settings
|
127
|
+
|
128
|
+
Sometimes you may want define default settings.
|
129
|
+
|
130
|
+
RailsSettings has generate a config YAML file in:
|
131
|
+
|
132
|
+
```yml
|
133
|
+
# config/app.yml
|
134
|
+
defaults: &defaults
|
135
|
+
github_token: "123456"
|
136
|
+
twitter_token: "<%= ENV["TWITTER_TOKEN"] %>"
|
137
|
+
foo:
|
138
|
+
bar: "Foo bar"
|
139
|
+
|
140
|
+
development:
|
141
|
+
<<: *defaults
|
142
|
+
|
143
|
+
test:
|
144
|
+
<<: *defaults
|
145
|
+
|
146
|
+
production:
|
147
|
+
<<: *defaults
|
148
|
+
```
|
149
|
+
|
150
|
+
And you can use by `Setting` model:
|
151
|
+
|
152
|
+
```
|
153
|
+
Setting.github_token
|
154
|
+
=> "123456"
|
155
|
+
Setting.github_token = "654321"
|
156
|
+
# Save into database.
|
157
|
+
Setting.github_token
|
158
|
+
# Read from databae / caching.
|
159
|
+
=> "654321"
|
160
|
+
Setting['foo.bar']
|
161
|
+
=> 'Foo bar'
|
162
|
+
```
|
163
|
+
|
164
|
+
NOTE: YAML setting it also under the cache scope, when you restart Rails application, cache will expire,
|
165
|
+
so when you want change default config, you need restart Rails application server.
|
166
|
+
|
167
|
+
### Caching flow:
|
168
|
+
|
169
|
+
```
|
170
|
+
Setting.foo -> Check Cache -> Exist - Write Cache -> Return
|
171
|
+
|
|
172
|
+
Check DB -> Exist -> Write Cache -> Return
|
173
|
+
|
|
174
|
+
Check Default -> Exist -> Write Cache -> Return
|
175
|
+
|
|
176
|
+
Return nil
|
177
|
+
```
|
178
|
+
|
179
|
+
## Change cache key
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
class Setting < RailsSettings::Base
|
183
|
+
cache_prefix { 'you-prefix' }
|
184
|
+
...
|
185
|
+
end
|
186
|
+
```
|
187
|
+
|
188
|
+
-----
|
189
|
+
|
190
|
+
## How to create a list, form to manage Settings?
|
191
|
+
|
192
|
+
If you want create an admin interface to editing the Settings, you can try methods in follow:
|
193
|
+
|
194
|
+
config/routes.rb
|
195
|
+
|
196
|
+
```rb
|
197
|
+
namespace :admin do
|
198
|
+
resources :settings
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|
202
|
+
|
203
|
+
app/controllers/admin/settings_controller.rb
|
204
|
+
|
205
|
+
```rb
|
206
|
+
module Admin
|
207
|
+
class SettingsController < ApplicationController
|
208
|
+
before_action :get_setting, only: [:edit, :update]
|
209
|
+
|
210
|
+
def index
|
211
|
+
@settings = Setting.get_all
|
212
|
+
end
|
213
|
+
|
214
|
+
def edit
|
215
|
+
end
|
216
|
+
|
217
|
+
def update
|
218
|
+
if @setting.value != params[:setting][:value]
|
219
|
+
@setting.value = YAML.load(params[:setting][:value])
|
220
|
+
@setting.save
|
221
|
+
redirect_to admin_settings_path, notice: 'Setting has updated.'
|
222
|
+
else
|
223
|
+
redirect_to admin_settings_path
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def get_setting
|
228
|
+
@setting = Setting.find_by(var: params[:id]) || Setting.new(var: params[:id])
|
229
|
+
@setting[:value] = Setting[params[:id]]
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
```
|
234
|
+
|
235
|
+
app/views/admin/settings/index.html.erb
|
236
|
+
|
237
|
+
```erb
|
238
|
+
<table>
|
239
|
+
<tr>
|
240
|
+
<th>Key</th>
|
241
|
+
<th></th>
|
242
|
+
</tr>
|
243
|
+
<% @settings.each_key do |key| %>
|
244
|
+
<tr>
|
245
|
+
<td><%= key %></td>
|
246
|
+
<td><%= link_to 'edit', edit_admin_setting_path(key) %></td>
|
247
|
+
</tr>
|
248
|
+
<% end %>
|
249
|
+
</table>
|
250
|
+
```
|
251
|
+
|
252
|
+
app/views/admin/settings/edit.html.erb
|
253
|
+
|
254
|
+
```erb
|
255
|
+
<%= form_for(@setting, url: admin_setting_path(@setting.var), method: 'patch') do |f| %>
|
256
|
+
<label><%= @setting.var %></label>
|
257
|
+
<%= f.textarea :value, rows: 10 %>
|
258
|
+
<%= f.submit %>
|
259
|
+
<% end %>
|
260
|
+
```
|
261
|
+
|
262
|
+
Also you may use [rails-settings-ui](https://github.com/accessd/rails-settings-ui) gem
|
263
|
+
for building ready to using interface with validations.
|
@@ -26,7 +26,8 @@ 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")
|
29
|
+
template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
30
|
+
template 'app.yml', File.join('config', "app.yml")
|
30
31
|
migration_template 'migration.rb', 'db/migrate/create_settings.rb'
|
31
32
|
end
|
32
33
|
end
|
@@ -1,15 +1,16 @@
|
|
1
|
-
require_relative 'rails-settings/base'
|
2
1
|
require_relative 'rails-settings/settings'
|
2
|
+
require_relative 'rails-settings/base'
|
3
3
|
require_relative 'rails-settings/cached_settings'
|
4
4
|
require_relative 'rails-settings/scoped_settings'
|
5
|
+
require_relative 'rails-settings/default'
|
5
6
|
require_relative 'rails-settings/extend'
|
6
7
|
require_relative 'rails-settings/version'
|
7
8
|
|
8
9
|
module RailsSettings
|
9
10
|
class Railtie < Rails::Railtie
|
10
11
|
initializer "rails_settings.active_record.initialization" do
|
11
|
-
RailsSettings::
|
12
|
-
RailsSettings::
|
12
|
+
RailsSettings::Base.after_commit :rewrite_cache, on: %i(create update)
|
13
|
+
RailsSettings::Base.after_commit :expire_cache, on: %i(destroy)
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
data/lib/rails-settings/base.rb
CHANGED
@@ -1,111 +1,55 @@
|
|
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_by_startup
|
17
|
+
@cache_prefix_by_startup ||= Time.now.to_f.to_s
|
42
18
|
end
|
43
19
|
|
44
|
-
|
45
|
-
|
46
|
-
var_name = var_name.to_s
|
47
|
-
obj = object(var_name)
|
48
|
-
raise SettingNotFound, "Setting variable \"#{var_name}\" not found" if obj.nil?
|
49
|
-
|
50
|
-
obj.destroy
|
51
|
-
true
|
20
|
+
def cache_prefix(&block)
|
21
|
+
@cache_prefix = block
|
52
22
|
end
|
53
23
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
vars.each do |record|
|
61
|
-
result[record.var] = record.value
|
62
|
-
end
|
63
|
-
default_keys = @@defaults.keys
|
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
|
24
|
+
def cache_key(var_name, scope_object)
|
25
|
+
scope = ["rails_settings_cached", cache_prefix_by_startup]
|
26
|
+
scope << @cache_prefix.call if @cache_prefix
|
27
|
+
scope << "#{scope_object.class.name}-#{scope_object.id}" if scope_object
|
28
|
+
scope << var_name.to_s
|
29
|
+
scope.join('/')
|
68
30
|
end
|
69
31
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
# get a setting value by [] notation
|
76
|
-
def [](var_name)
|
77
|
-
object(var_name).try(:value) || @@defaults[var_name.to_s]
|
32
|
+
def [](key)
|
33
|
+
val = Rails.cache.fetch(cache_key(key, @object)) do
|
34
|
+
super(key)
|
35
|
+
end
|
36
|
+
val
|
78
37
|
end
|
79
38
|
|
80
39
|
# set a setting value by [] notation
|
81
40
|
def []=(var_name, value)
|
82
|
-
|
41
|
+
super
|
83
42
|
|
84
|
-
|
85
|
-
record.value = value
|
86
|
-
record.save!
|
43
|
+
Rails.cache.write(cache_key(var_name, @object),value)
|
87
44
|
|
88
45
|
value
|
89
46
|
end
|
90
47
|
|
91
|
-
def
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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')
|
48
|
+
def save_default(key, value)
|
49
|
+
Kernel.warn 'DEPRECATION WARNING: RailsSettings save_default is deprecated and it will removed in 0.7.0. ' <<
|
50
|
+
'Please use YAML file for default setting.'
|
51
|
+
return false unless self[key].nil?
|
52
|
+
self[key] = value
|
109
53
|
end
|
110
54
|
end
|
111
55
|
end
|
@@ -1,54 +1,9 @@
|
|
1
1
|
module RailsSettings
|
2
2
|
class CachedSettings < Base
|
3
|
-
def
|
4
|
-
|
5
|
-
|
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
|
3
|
+
def self.inherited(subclass)
|
4
|
+
Kernel.warn 'DEPRECATION WARNING: RailsSettings::CachedSettings is deprecated and it will removed in 0.7.0. ' <<
|
5
|
+
'Please use RailsSettings::Base instead.'
|
6
|
+
super(subclass)
|
52
7
|
end
|
53
8
|
end
|
54
9
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module RailsSettings
|
2
|
+
class Default < ::Hash
|
3
|
+
class MissingKey < StandardError; end
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def enabled?
|
7
|
+
source_path && File.exists?(source_path)
|
8
|
+
end
|
9
|
+
|
10
|
+
def source(value = nil)
|
11
|
+
@source ||= value
|
12
|
+
end
|
13
|
+
|
14
|
+
def source_path
|
15
|
+
@source || Rails.root.join('config/app.yml')
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](key)
|
19
|
+
# foo.bar.dar Nested fetch value
|
20
|
+
keys = key.to_s.split('.')
|
21
|
+
val = instance
|
22
|
+
keys.each do |k|
|
23
|
+
val = val.fetch(k.to_s, nil)
|
24
|
+
break if val.nil?
|
25
|
+
end
|
26
|
+
val
|
27
|
+
end
|
28
|
+
|
29
|
+
def instance
|
30
|
+
return @instance if defined? @instance
|
31
|
+
@instance = new
|
32
|
+
@instance
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
content = open(self.class.source_path).read
|
38
|
+
hash = content.empty? ? {} : YAML.load(ERB.new(content).result).to_hash
|
39
|
+
hash = hash[Rails.env] || {}
|
40
|
+
self.replace hash
|
41
|
+
end
|
42
|
+
end
|
43
|
+
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
|
+
def method_missing(method, *args)
|
22
|
+
method_name = method.to_s
|
23
|
+
super(method, *args)
|
24
|
+
rescue NoMethodError
|
25
|
+
# set a value for a variable
|
26
|
+
if method_name[-1] == '='
|
27
|
+
var_name = method_name.sub('=', '')
|
28
|
+
value = args.first
|
29
|
+
self[var_name] = value
|
30
|
+
else
|
31
|
+
# retrieve a value
|
32
|
+
self[method_name]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# destroy the specified settings record
|
37
|
+
def destroy(var_name)
|
38
|
+
var_name = var_name.to_s
|
39
|
+
obj = object(var_name)
|
40
|
+
raise SettingNotFound, "Setting variable \"#{var_name}\" not found" if obj.nil?
|
41
|
+
|
42
|
+
obj.destroy
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
# retrieve all settings as a hash (optionally starting with a given namespace)
|
47
|
+
def get_all(starting_with = nil)
|
48
|
+
vars = thing_scoped.select('var, value')
|
49
|
+
vars = vars.where("var LIKE '#{starting_with}%'") if starting_with
|
50
|
+
|
51
|
+
result = {}
|
52
|
+
vars.each do |record|
|
53
|
+
result[record.var] = record.value
|
54
|
+
end
|
55
|
+
|
56
|
+
defaults = {}
|
57
|
+
if Default.enabled?
|
58
|
+
defaults = starting_with.nil? ? Default.instance : Default.instance.fetch(starting_with, {})
|
59
|
+
end
|
60
|
+
|
61
|
+
result.merge! defaults
|
62
|
+
|
63
|
+
result.with_indifferent_access
|
64
|
+
end
|
65
|
+
|
66
|
+
def where(sql = nil)
|
67
|
+
vars = thing_scoped.where(sql) if sql
|
68
|
+
vars
|
69
|
+
end
|
70
|
+
|
71
|
+
# get a setting value by [] notation
|
72
|
+
def [](var_name)
|
73
|
+
if var = object(var_name)
|
74
|
+
val = var.value
|
75
|
+
elsif Default.enabled?
|
76
|
+
val = Default[var_name]
|
77
|
+
else
|
78
|
+
val = nil
|
79
|
+
end
|
80
|
+
val
|
81
|
+
end
|
82
|
+
|
83
|
+
# set a setting value by [] notation
|
84
|
+
def []=(var_name, value)
|
85
|
+
var_name = var_name.to_s
|
86
|
+
|
87
|
+
record = object(var_name) || thing_scoped.new(var: var_name)
|
88
|
+
record.value = value
|
89
|
+
record.save!
|
90
|
+
|
91
|
+
value
|
92
|
+
end
|
93
|
+
|
94
|
+
def merge!(var_name, hash_value)
|
95
|
+
raise ArgumentError unless hash_value.is_a?(Hash)
|
96
|
+
|
97
|
+
old_value = self[var_name] || {}
|
98
|
+
raise TypeError, "Existing value is not a hash, can't merge!" unless old_value.is_a?(Hash)
|
99
|
+
|
100
|
+
new_value = old_value.merge(hash_value)
|
101
|
+
self[var_name] = new_value if new_value != old_value
|
102
|
+
|
103
|
+
new_value
|
104
|
+
end
|
105
|
+
|
106
|
+
def object(var_name)
|
107
|
+
thing_scoped.where(var: var_name.to_s).first
|
108
|
+
end
|
109
|
+
|
110
|
+
def thing_scoped
|
111
|
+
unscoped.where('thing_type is NULL and thing_id is NULL')
|
112
|
+
end
|
113
|
+
|
114
|
+
def source(filename)
|
115
|
+
Default.source(filename)
|
116
|
+
end
|
7
117
|
end
|
8
118
|
end
|
9
119
|
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.6.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: 2016-04-
|
14
|
+
date: 2016-04-20 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rails
|
@@ -40,11 +40,13 @@ extra_rdoc_files: []
|
|
40
40
|
files:
|
41
41
|
- README.md
|
42
42
|
- lib/generators/settings/install_generator.rb
|
43
|
+
- lib/generators/settings/templates/app.yml
|
43
44
|
- lib/generators/settings/templates/migration.rb
|
44
45
|
- lib/generators/settings/templates/model.rb
|
45
46
|
- lib/rails-settings-cached.rb
|
46
47
|
- lib/rails-settings/base.rb
|
47
48
|
- lib/rails-settings/cached_settings.rb
|
49
|
+
- lib/rails-settings/default.rb
|
48
50
|
- lib/rails-settings/extend.rb
|
49
51
|
- lib/rails-settings/scoped_settings.rb
|
50
52
|
- lib/rails-settings/settings.rb
|