rails-settings-cached 0.4.1 → 2.0.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/MIT-LICENSE +21 -0
- data/README.md +233 -179
- data/Rakefile +30 -0
- data/lib/generators/settings/install_generator.rb +43 -0
- data/lib/generators/settings/templates/migration.rb +5 -7
- data/lib/generators/settings/templates/model.rb +9 -1
- data/lib/rails-settings/base.rb +121 -0
- data/lib/rails-settings/railtie.rb +9 -0
- data/lib/rails-settings/version.rb +9 -0
- data/lib/rails-settings-cached.rb +8 -4
- metadata +89 -22
- data/lib/generators/settings/settings_generator.rb +0 -30
- data/lib/rails-settings/cached_settings.rb +0 -25
- data/lib/rails-settings/extend.rb +0 -37
- data/lib/rails-settings/scoped_settings.rb +0 -13
- data/lib/rails-settings/settings.rb +0 -118
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e89d0b87824703140e5d9182ade7936b22045bde791ba86d805dfbde9614f7b7
|
4
|
+
data.tar.gz: 2a3643dd2c6b3b837c3a4b1361651ca0a5b468336e038a38d1aaaa3bc659e151
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6b9209c170d1b5d34b62496533936c4e8598bc963fb5bd1fbb3a8c5b86424e6c7986fb300eb4aebc89ce7e13f86d083588bef06e93c5c6927b18ccf2465e5e6
|
7
|
+
data.tar.gz: 7b7b05d0794663008292b3630c99c160f8fc54cc0b9e8b958d46052cb63ce94f9eff4d012d06b2676551cfc805502d890e5313a887d3611bfb6fdbd0ffb2d3d9
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2006 Alex Wayne
|
2
|
+
Some additional features added 2009 by Georg Ledermann
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,179 +1,233 @@
|
|
1
|
-
# Settings
|
2
|
-
|
3
|
-
This
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
```ruby
|
75
|
-
Setting.
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
Setting.
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
Setting
|
98
|
-
Setting
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
Setting.
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
Setting.
|
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
|
-
|
1
|
+
# Rails Settings Cached
|
2
|
+
|
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,
|
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
|
7
|
+
of object. Strings, numbers, arrays, or any object.
|
8
|
+
|
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.
|
12
|
+
|
13
|
+
## Status
|
14
|
+
|
15
|
+
[](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)
|
16
|
+
|
17
|
+
## Setup
|
18
|
+
|
19
|
+
Edit your Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem "rails-settings-cached"
|
23
|
+
```
|
24
|
+
|
25
|
+
Generate your settings:
|
26
|
+
|
27
|
+
```bash
|
28
|
+
$ rails g settings:install
|
29
|
+
```
|
30
|
+
|
31
|
+
If you want custom model name:
|
32
|
+
|
33
|
+
```bash
|
34
|
+
$ rails g settings:install
|
35
|
+
```
|
36
|
+
|
37
|
+
Or use a custom name:
|
38
|
+
|
39
|
+
```bash
|
40
|
+
$ rails g settings:install SiteConfig
|
41
|
+
```
|
42
|
+
|
43
|
+
You will get `app/models/setting.rb`
|
44
|
+
|
45
|
+
```rb
|
46
|
+
class Setting < RailsSettings::Base
|
47
|
+
# cache_prefix { "v1" }
|
48
|
+
|
49
|
+
field :host, default: "http://example.com"
|
50
|
+
field :readonly_item, type: :integer, default: 100, readonly: true
|
51
|
+
field :user_limits, type: :integer, default: 20
|
52
|
+
field :admin_emails, type: :array, default: %w[admin@rubyonrails.org]
|
53
|
+
field :captcha_enable, type: :boolean, default: 1
|
54
|
+
field :notification_options, type: :hash, default: {
|
55
|
+
send_all: true,
|
56
|
+
logging: true,
|
57
|
+
sender_email: "foo@bar.com"
|
58
|
+
}
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
You must use `field` method to statement the setting keys, otherwice you can't use it.
|
63
|
+
|
64
|
+
Now just put that migration in the database with:
|
65
|
+
|
66
|
+
```bash
|
67
|
+
rake db:migrate
|
68
|
+
```
|
69
|
+
|
70
|
+
## Usage
|
71
|
+
|
72
|
+
The syntax is easy. First, lets create some settings to keep track of:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
irb > Setting.host
|
76
|
+
"http://example.com"
|
77
|
+
irb > Setting.host = "https://your-host.com"
|
78
|
+
irb > Setting.host
|
79
|
+
"https://your-host.com"
|
80
|
+
|
81
|
+
irb > Setting.user_limits
|
82
|
+
20
|
83
|
+
irb > Setting.user_limits = "30"
|
84
|
+
irb > Setting.user_limits
|
85
|
+
30
|
86
|
+
irb > Setting.user_limits = 45
|
87
|
+
irb > Setting.user_limits
|
88
|
+
45
|
89
|
+
|
90
|
+
irb > Setting.captcha_enable
|
91
|
+
1
|
92
|
+
irb > Setting.captcha_enable?
|
93
|
+
true
|
94
|
+
irb > Setting.captcha_enable = "0"
|
95
|
+
irb > Setting.captcha_enable
|
96
|
+
false
|
97
|
+
irb > Setting.captcha_enable = "1"
|
98
|
+
irb > Setting.captcha_enable
|
99
|
+
true
|
100
|
+
irb > Setting.captcha_enable = "false"
|
101
|
+
irb > Setting.captcha_enable
|
102
|
+
false
|
103
|
+
irb > Setting.captcha_enable = "true"
|
104
|
+
irb > Setting.captcha_enable
|
105
|
+
true
|
106
|
+
irb > Setting.captcha_enable?
|
107
|
+
true
|
108
|
+
|
109
|
+
irb > Setting.admin_emails
|
110
|
+
["admin@rubyonrails.org"]
|
111
|
+
irb > Setting.admin_emails = %w[foo@bar.com bar@dar.com]
|
112
|
+
irb > Setting.admin_emails
|
113
|
+
["foo@bar.com", "bar@dar.com"]
|
114
|
+
irb > Setting.admin_emails = "huacnlee@gmail.com,admin@admin.com\nadmin@rubyonrails.org"
|
115
|
+
irb > Setting.admin_emails
|
116
|
+
["huacnlee@gmail.com", "admin@admin.com", "admin@rubyonrails.org"]
|
117
|
+
|
118
|
+
irb > Setting.notification_options
|
119
|
+
{
|
120
|
+
send_all: true,
|
121
|
+
logging: true,
|
122
|
+
sender_email: "foo@bar.com"
|
123
|
+
}
|
124
|
+
irb > Setting.notification_options = {
|
125
|
+
sender_email: "notice@rubyonrails.org"
|
126
|
+
}
|
127
|
+
irb > Setting.notification_options
|
128
|
+
{
|
129
|
+
sender_email: "notice@rubyonrails.org"
|
130
|
+
}
|
131
|
+
```
|
132
|
+
|
133
|
+
### Caching flow:
|
134
|
+
|
135
|
+
```
|
136
|
+
Setting.host -> Check Cache -> Exist - Get value of key for cache -> Return
|
137
|
+
|
|
138
|
+
Fetch all key and values from DB -> Write Cache -> Get value of key for cache -> return
|
139
|
+
|
|
140
|
+
Return default value or nil
|
141
|
+
```
|
142
|
+
|
143
|
+
In each Setting keys call, we will load the cache/db and save in Thread.current for avoid hit cache/db.
|
144
|
+
|
145
|
+
Each key update will expires the cache, so do not add some frequent update key.
|
146
|
+
|
147
|
+
## Change cache key
|
148
|
+
|
149
|
+
Some times you may need to force update cache, now you can use `cache_prefix`
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
class Setting < RailsSettings::Base
|
153
|
+
cache_prefix { "you-prefix" }
|
154
|
+
...
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
-----
|
159
|
+
|
160
|
+
## How to manage Settings in admin interface?
|
161
|
+
|
162
|
+
If you want create an admin interface to editing the Settings, you can try methods in follow:
|
163
|
+
|
164
|
+
config/routes.rb
|
165
|
+
|
166
|
+
```rb
|
167
|
+
namespace :admin do
|
168
|
+
resources :settings
|
169
|
+
end
|
170
|
+
```
|
171
|
+
|
172
|
+
|
173
|
+
app/controllers/admin/settings_controller.rb
|
174
|
+
|
175
|
+
```rb
|
176
|
+
module Admin
|
177
|
+
class SettingsController < ApplicationController
|
178
|
+
before_action :get_setting, only: [:edit, :update]
|
179
|
+
|
180
|
+
def show
|
181
|
+
end
|
182
|
+
|
183
|
+
def create
|
184
|
+
setting_params.keys.each do |key|
|
185
|
+
next if key.to_s == "site_logo"
|
186
|
+
Setting.send("#{key}=", setting_params[key].strip) unless setting_params[key].nil?
|
187
|
+
end
|
188
|
+
redirect_to admin_settings_path(notice: "Setting was successfully updated.")
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
private
|
193
|
+
def setting_params
|
194
|
+
params.require(:setting).permit(:host, :user_limits, :admin_emails,
|
195
|
+
:captcha_enable, :notification_options)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
```
|
200
|
+
|
201
|
+
app/views/admin/settings/show.html.erb
|
202
|
+
|
203
|
+
```erb
|
204
|
+
<%= form_for(Setting.new, url: admin_settings_path) do |f| %>
|
205
|
+
<div class="form-group">
|
206
|
+
<label class="control-label">Host</label>
|
207
|
+
<%= f.text_field :host, value: Setting.host, class: "form-control", placeholder: "http://localhost" %>
|
208
|
+
</div>
|
209
|
+
|
210
|
+
<div class="form-group form-checkbox">
|
211
|
+
<label>
|
212
|
+
<%= f.check_box :captcha_enable, checked: Setting.captcha_enable? %>
|
213
|
+
Enable/Disable Captcha
|
214
|
+
</label>
|
215
|
+
</div>
|
216
|
+
|
217
|
+
<div class="form-group">
|
218
|
+
<label class="control-label">Admin Emails</label>
|
219
|
+
<%= f.text_area :admin_emails, value: Setting.admin_emails.join("\n"), class: "form-control" %>
|
220
|
+
</div>
|
221
|
+
|
222
|
+
<div class="form-group">
|
223
|
+
<label class="control-label">Notification options</label>
|
224
|
+
<%= f.text_area :notification_options, value: YAML.dump(Setting.notification_options), class: "form-control", style: "height: 180px;" %>
|
225
|
+
<div class="form-text">
|
226
|
+
Use YAML format to config the SMTP_html
|
227
|
+
</details>
|
228
|
+
<% end %>
|
229
|
+
```
|
230
|
+
|
231
|
+
## Use case:
|
232
|
+
|
233
|
+
- [ruby-china/ruby-china](https://github.com/ruby-china/ruby-china)
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "bundler/setup"
|
5
|
+
rescue LoadError
|
6
|
+
puts "You must `gem install bundler` and `bundle install` to run rake tasks"
|
7
|
+
end
|
8
|
+
|
9
|
+
require "rdoc/task"
|
10
|
+
|
11
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
12
|
+
rdoc.rdoc_dir = "rdoc"
|
13
|
+
rdoc.title = "Rails Settings Cached"
|
14
|
+
rdoc.options << "--line-numbers"
|
15
|
+
rdoc.rdoc_files.include("README.md")
|
16
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
17
|
+
end
|
18
|
+
|
19
|
+
require "bundler/gem_tasks"
|
20
|
+
|
21
|
+
require "rake/testtask"
|
22
|
+
|
23
|
+
Rake::TestTask.new(:test) do |t|
|
24
|
+
t.libs << "test"
|
25
|
+
t.pattern = "test/**/*_test.rb"
|
26
|
+
t.verbose = false
|
27
|
+
t.warning = false
|
28
|
+
end
|
29
|
+
|
30
|
+
task default: :test
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
require "rails/generators/migration"
|
5
|
+
|
6
|
+
module Settings
|
7
|
+
class InstallGenerator < Rails::Generators::NamedBase
|
8
|
+
desc "Generate RailsSettings files."
|
9
|
+
include Rails::Generators::Migration
|
10
|
+
|
11
|
+
argument :name, type: :string, default: "setting"
|
12
|
+
|
13
|
+
source_root File.expand_path("../templates", __FILE__)
|
14
|
+
|
15
|
+
@@migrations = false
|
16
|
+
|
17
|
+
def self.next_migration_number(dirname) #:nodoc:
|
18
|
+
if ActiveRecord::Base.timestamped_migrations
|
19
|
+
if @@migrations
|
20
|
+
(current_migration_number(dirname) + 1)
|
21
|
+
else
|
22
|
+
@@migrations = true
|
23
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
24
|
+
end
|
25
|
+
else
|
26
|
+
format "%.3d", current_migration_number(dirname) + 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def install_setting
|
31
|
+
template "model.rb", File.join("app/models", class_path, "#{file_name}.rb")
|
32
|
+
migration_template "migration.rb", "db/migrate/create_settings.rb", migration_version: migration_version
|
33
|
+
end
|
34
|
+
|
35
|
+
def rails5?
|
36
|
+
Rails.version.start_with? "5"
|
37
|
+
end
|
38
|
+
|
39
|
+
def migration_version
|
40
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if rails5?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,14 +1,12 @@
|
|
1
|
-
class CreateSettings < ActiveRecord::Migration
|
1
|
+
class CreateSettings < ActiveRecord::Migration<%= migration_version %>
|
2
2
|
def self.up
|
3
3
|
create_table :settings do |t|
|
4
|
-
t.string
|
5
|
-
t.text
|
6
|
-
t.integer :thing_id, :null => true
|
7
|
-
t.string :thing_type, :limit => 30, :null => true
|
4
|
+
t.string :var, null: false
|
5
|
+
t.text :value, null: true
|
8
6
|
t.timestamps
|
9
7
|
end
|
10
|
-
|
11
|
-
add_index :settings,
|
8
|
+
|
9
|
+
add_index :settings, %i(var), unique: true
|
12
10
|
end
|
13
11
|
|
14
12
|
def self.down
|
@@ -1,2 +1,10 @@
|
|
1
|
-
|
1
|
+
# RailsSettings Model
|
2
|
+
class <%= class_name %> < RailsSettings::Base
|
3
|
+
cache_prefix { "v1" }
|
4
|
+
|
5
|
+
# Define your fields
|
6
|
+
# field :host, type: :string, default: "http://localhost:3000"
|
7
|
+
# field :default_locale, default: "en", type: :string
|
8
|
+
# field :confirmable_enable, default: "0", type: :boolean
|
9
|
+
# field :admin_emails, default: "admin@rubyonrails.org", type: :array
|
2
10
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsSettings
|
4
|
+
class Base < ActiveRecord::Base
|
5
|
+
class SettingNotFound < RuntimeError; end
|
6
|
+
|
7
|
+
SEPARATOR_REGEXP = /[\s,]/
|
8
|
+
self.table_name = table_name_prefix + "settings"
|
9
|
+
|
10
|
+
# get the value field, YAML decoded
|
11
|
+
def value
|
12
|
+
YAML.load(self[:value]) if self[:value].present?
|
13
|
+
end
|
14
|
+
|
15
|
+
# set the value field, YAML encoded
|
16
|
+
def value=(new_value)
|
17
|
+
self[:value] = new_value.to_yaml
|
18
|
+
end
|
19
|
+
|
20
|
+
def expire_cache
|
21
|
+
Thread.current[:rails_settings_all_settings] = nil
|
22
|
+
Rails.cache.delete(self.class.cache_key)
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def field(key, **opts)
|
27
|
+
_define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly])
|
28
|
+
end
|
29
|
+
|
30
|
+
def cache_prefix(&block)
|
31
|
+
@cache_prefix = block
|
32
|
+
end
|
33
|
+
|
34
|
+
def cache_key
|
35
|
+
scope = ["rails-settings-cached"]
|
36
|
+
scope << @cache_prefix.call if @cache_prefix
|
37
|
+
scope.join("/")
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def _define_field(key, default: nil, type: :string, readonly: false)
|
42
|
+
self.class.define_method(key) do
|
43
|
+
val = self.send(:_value_of, key)
|
44
|
+
result = nil
|
45
|
+
if !val.nil?
|
46
|
+
result = val
|
47
|
+
else
|
48
|
+
result = default
|
49
|
+
result = default.call if default.is_a?(Proc)
|
50
|
+
end
|
51
|
+
|
52
|
+
result = self.send(:_covert_string_to_typeof_value, type, result)
|
53
|
+
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
unless readonly
|
58
|
+
self.class.define_method("#{key}=") do |value|
|
59
|
+
var_name = key.to_s
|
60
|
+
|
61
|
+
record = find_by(var: var_name) || new(var: var_name)
|
62
|
+
value = self.send(:_covert_string_to_typeof_value, type, value)
|
63
|
+
|
64
|
+
record.value = value
|
65
|
+
record.save!
|
66
|
+
|
67
|
+
value
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
if type == :boolean
|
72
|
+
self.class.define_method("#{key}?") do
|
73
|
+
val = self.send(:_value_of, key)
|
74
|
+
val == "true" || val == "1"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def _covert_string_to_typeof_value(type, value)
|
80
|
+
return value unless value.is_a?(String) || value.is_a?(Integer)
|
81
|
+
|
82
|
+
case type
|
83
|
+
when :boolean
|
84
|
+
return value == "true" || value == "1" || value == 1 || value == true
|
85
|
+
when :array
|
86
|
+
return value.split(SEPARATOR_REGEXP).reject { |str| str.empty? }
|
87
|
+
when :hash
|
88
|
+
value = YAML.load(value).to_hash rescue {}
|
89
|
+
value.deep_stringify_keys!
|
90
|
+
return value
|
91
|
+
when :integer
|
92
|
+
return value.to_i
|
93
|
+
else
|
94
|
+
value
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def _value_of(var_name)
|
99
|
+
raise "#{self.table_name} does not exist." unless table_exists?
|
100
|
+
|
101
|
+
_all_settings[var_name.to_s]
|
102
|
+
end
|
103
|
+
|
104
|
+
def rails_initialized?
|
105
|
+
Rails.application && Rails.application.initialized?
|
106
|
+
end
|
107
|
+
|
108
|
+
def _all_settings
|
109
|
+
raise "You can use settings before Rails initialize." unless rails_initialized?
|
110
|
+
Thread.current[:rails_settings_all_settings] ||= begin
|
111
|
+
Rails.cache.fetch(self.cache_key, expires_in: 1.week) do
|
112
|
+
vars = unscoped.select("var, value")
|
113
|
+
result = {}
|
114
|
+
vars.each { |record| result[record.var] = record.value }
|
115
|
+
result.with_indifferent_access
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "rails-settings/base"
|
4
|
+
require_relative "rails-settings/railtie"
|
5
|
+
require_relative "rails-settings/version"
|
6
|
+
|
7
|
+
module RailsSettings
|
8
|
+
end
|
metadata
CHANGED
@@ -1,17 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-settings-cached
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Squeegy
|
8
|
-
- Georg Ledermann
|
9
|
-
- 100hz
|
10
7
|
- Jason Lee
|
11
8
|
autorequire:
|
12
9
|
bindir: bin
|
13
10
|
cert_chain: []
|
14
|
-
date:
|
11
|
+
date: 2019-04-26 00:00:00.000000000 Z
|
15
12
|
dependencies:
|
16
13
|
- !ruby/object:Gem::Dependency
|
17
14
|
name: rails
|
@@ -19,29 +16,105 @@ dependencies:
|
|
19
16
|
requirements:
|
20
17
|
- - ">="
|
21
18
|
- !ruby/object:Gem::Version
|
22
|
-
version: 4.
|
19
|
+
version: 4.2.0
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: 4.
|
30
|
-
|
26
|
+
version: 4.2.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: codecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: "\n This is improved from rails-settings, added caching.\n Settings
|
98
|
+
plugin for Rails that makes managing a table of global key,\n value pairs easy.
|
99
|
+
Think of it like a global Hash stored in you database,\n that uses simple ActiveRecord
|
100
|
+
like methods for manipulation.\n\n Keep track of any global setting that you dont
|
101
|
+
want to hard code into your rails app.\n You can store any kind of object. Strings,
|
102
|
+
numbers, arrays, or any object.\n "
|
31
103
|
email: huacnlee@gmail.com
|
32
104
|
executables: []
|
33
105
|
extensions: []
|
34
106
|
extra_rdoc_files: []
|
35
107
|
files:
|
108
|
+
- MIT-LICENSE
|
36
109
|
- README.md
|
37
|
-
-
|
110
|
+
- Rakefile
|
111
|
+
- lib/generators/settings/install_generator.rb
|
38
112
|
- lib/generators/settings/templates/migration.rb
|
39
113
|
- lib/generators/settings/templates/model.rb
|
40
114
|
- lib/rails-settings-cached.rb
|
41
|
-
- lib/rails-settings/
|
42
|
-
- lib/rails-settings/
|
43
|
-
- lib/rails-settings/
|
44
|
-
- lib/rails-settings/settings.rb
|
115
|
+
- lib/rails-settings/base.rb
|
116
|
+
- lib/rails-settings/railtie.rb
|
117
|
+
- lib/rails-settings/version.rb
|
45
118
|
homepage: https://github.com/huacnlee/rails-settings-cached
|
46
119
|
licenses: []
|
47
120
|
metadata: {}
|
@@ -53,21 +126,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
126
|
requirements:
|
54
127
|
- - ">="
|
55
128
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
129
|
+
version: '2.5'
|
57
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
131
|
requirements:
|
59
132
|
- - ">="
|
60
133
|
- !ruby/object:Gem::Version
|
61
134
|
version: '0'
|
62
135
|
requirements: []
|
63
|
-
|
64
|
-
rubygems_version: 2.2.2
|
136
|
+
rubygems_version: 3.0.1
|
65
137
|
signing_key:
|
66
138
|
specification_version: 4
|
67
|
-
summary:
|
68
|
-
that makes managing a table of global key, value pairs easy. Think of it like a
|
69
|
-
global Hash stored in you database, that uses simple ActiveRecord like methods for
|
70
|
-
manipulation. Keep track of any global setting that you dont want to hard code
|
71
|
-
into your rails app. You can store any kind of object. Strings, numbers, arrays,
|
72
|
-
or any object. Ported to Rails 3!
|
139
|
+
summary: Settings plugin for Rails that makes managing a table of global keys.
|
73
140
|
test_files: []
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'rails/generators/migration'
|
2
|
-
|
3
|
-
class SettingsGenerator < Rails::Generators::NamedBase
|
4
|
-
include Rails::Generators::Migration
|
5
|
-
|
6
|
-
argument :name, :type => :string, :default => "my_settings"
|
7
|
-
|
8
|
-
source_root File.expand_path('../templates', __FILE__)
|
9
|
-
|
10
|
-
@@migrations = false
|
11
|
-
|
12
|
-
def self.next_migration_number(dirname) #:nodoc:
|
13
|
-
if ActiveRecord::Base.timestamped_migrations
|
14
|
-
if @@migrations
|
15
|
-
(current_migration_number(dirname) + 1)
|
16
|
-
else
|
17
|
-
@@migrations = true
|
18
|
-
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
19
|
-
end
|
20
|
-
else
|
21
|
-
"%.3d" % (current_migration_number(dirname) + 1)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def settings
|
26
|
-
#generate(:model, name, "--skip-migration")
|
27
|
-
template "model.rb", File.join("app/models",class_path,"#{file_name}.rb"), :force => true
|
28
|
-
migration_template "migration.rb", "db/migrate/create_settings.rb"
|
29
|
-
end
|
30
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module RailsSettings
|
2
|
-
class CachedSettings < Settings
|
3
|
-
after_update :rewrite_cache
|
4
|
-
after_create :rewrite_cache
|
5
|
-
def rewrite_cache
|
6
|
-
Rails.cache.write("settings:#{self.var}", self.value)
|
7
|
-
end
|
8
|
-
|
9
|
-
after_destroy { |record| Rails.cache.delete("settings:#{record.var}") }
|
10
|
-
|
11
|
-
def self.[](var_name)
|
12
|
-
cache_key = "settings:#{var_name}"
|
13
|
-
obj = Rails.cache.fetch(cache_key) {
|
14
|
-
super(var_name)
|
15
|
-
}
|
16
|
-
obj == nil ? @@defaults[var_name.to_s] : obj
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.save_default(key,value)
|
20
|
-
if self.send(key) == nil
|
21
|
-
self.send("#{key}=",value)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module RailsSettings
|
2
|
-
module Extend
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
included do
|
6
|
-
scope :with_settings, -> {
|
7
|
-
joins("JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
|
8
|
-
settings.thing_type = '#{self.base_class.name}')")
|
9
|
-
.select("DISTINCT #{self.table_name}.*")
|
10
|
-
}
|
11
|
-
|
12
|
-
|
13
|
-
scope :with_settings_for, ->(var) {
|
14
|
-
joins("JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
|
15
|
-
settings.thing_type = '#{self.base_class.name}') AND settings.var = '#{var}'")
|
16
|
-
}
|
17
|
-
|
18
|
-
scope :without_settings, -> {
|
19
|
-
joins("LEFT JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND settings.thing_type = '#{self.base_class.name}')")
|
20
|
-
.where("settings.id IS NULL")
|
21
|
-
}
|
22
|
-
|
23
|
-
scope :without_settings_for, ->(var) {
|
24
|
-
where('settings.id IS NULL')
|
25
|
-
.joins("LEFT JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
|
26
|
-
settings.thing_type = '#{self.base_class.name}') AND settings.var = '#{var}'")
|
27
|
-
}
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
def settings
|
32
|
-
ScopedSettings.for_thing(self)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
|
@@ -1,118 +0,0 @@
|
|
1
|
-
module RailsSettings
|
2
|
-
class Settings < ActiveRecord::Base
|
3
|
-
|
4
|
-
self.table_name = table_name_prefix + 'settings'
|
5
|
-
|
6
|
-
class SettingNotFound < RuntimeError; end
|
7
|
-
|
8
|
-
cattr_accessor :defaults
|
9
|
-
@@defaults = {}.with_indifferent_access
|
10
|
-
|
11
|
-
# Support old plugin
|
12
|
-
if defined?(SettingsDefaults::DEFAULTS)
|
13
|
-
@@defaults = SettingsDefaults::DEFAULTS.with_indifferent_access
|
14
|
-
end
|
15
|
-
|
16
|
-
#get or set a variable with the variable as the called method
|
17
|
-
def self.method_missing(method, *args)
|
18
|
-
method_name = method.to_s
|
19
|
-
super(method, *args)
|
20
|
-
rescue NoMethodError
|
21
|
-
#set a value for a variable
|
22
|
-
if method_name =~ /=$/
|
23
|
-
var_name = method_name.gsub('=', '')
|
24
|
-
value = args.first
|
25
|
-
self[var_name] = value
|
26
|
-
#retrieve a value
|
27
|
-
else
|
28
|
-
self[method_name]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
#destroy the specified settings record
|
33
|
-
def self.destroy(var_name)
|
34
|
-
var_name = var_name.to_s
|
35
|
-
obj = object(var_name)
|
36
|
-
unless obj.nil?
|
37
|
-
obj.destroy
|
38
|
-
true
|
39
|
-
else
|
40
|
-
raise SettingNotFound, "Setting variable \"#{var_name}\" not found"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
#retrieve all settings as a hash (optionally starting with a given namespace)
|
45
|
-
def self.get_all(starting_with = nil)
|
46
|
-
vars = thing_scoped.select("var,value")
|
47
|
-
if starting_with
|
48
|
-
vars = vars.where("var LIKE '#{starting_with}%'")
|
49
|
-
end
|
50
|
-
|
51
|
-
result = {}
|
52
|
-
vars.each do |record|
|
53
|
-
result[record.var] = record.value
|
54
|
-
end
|
55
|
-
result.with_indifferent_access
|
56
|
-
end
|
57
|
-
|
58
|
-
def self.where(sql = nil)
|
59
|
-
if sql
|
60
|
-
vars = thing_scoped.where(sql)
|
61
|
-
end
|
62
|
-
vars
|
63
|
-
end
|
64
|
-
|
65
|
-
#get a setting value by [] notation
|
66
|
-
def self.[](var_name)
|
67
|
-
if var = object(var_name)
|
68
|
-
var.value
|
69
|
-
elsif @@defaults[var_name.to_s]
|
70
|
-
@@defaults[var_name.to_s]
|
71
|
-
else
|
72
|
-
nil
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
#set a setting value by [] notation
|
77
|
-
def self.[]=(var_name, value)
|
78
|
-
var_name = var_name.to_s
|
79
|
-
|
80
|
-
record = object(var_name) || thing_scoped.new(:var => var_name)
|
81
|
-
record.value = value
|
82
|
-
record.save!
|
83
|
-
|
84
|
-
value
|
85
|
-
end
|
86
|
-
|
87
|
-
def self.merge!(var_name, hash_value)
|
88
|
-
raise ArgumentError unless hash_value.is_a?(Hash)
|
89
|
-
|
90
|
-
old_value = self[var_name] || {}
|
91
|
-
raise TypeError, "Existing value is not a hash, can't merge!" unless old_value.is_a?(Hash)
|
92
|
-
|
93
|
-
new_value = old_value.merge(hash_value)
|
94
|
-
self[var_name] = new_value if new_value != old_value
|
95
|
-
|
96
|
-
new_value
|
97
|
-
end
|
98
|
-
|
99
|
-
def self.object(var_name)
|
100
|
-
thing_scoped.where(:var => var_name.to_s).first
|
101
|
-
end
|
102
|
-
|
103
|
-
#get the value field, YAML decoded
|
104
|
-
def value
|
105
|
-
YAML::load(self[:value])
|
106
|
-
end
|
107
|
-
|
108
|
-
#set the value field, YAML encoded
|
109
|
-
def value=(new_value)
|
110
|
-
self[:value] = new_value.to_yaml
|
111
|
-
end
|
112
|
-
|
113
|
-
def self.thing_scoped
|
114
|
-
unscoped.where("thing_type is NULL and thing_id is NULL")
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
118
|
-
end
|