rails-settings-cached 0.7.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eba484df56932a47956229096367746c7ffdeb979c61e2f9bcadbad09c0fd0a6
4
- data.tar.gz: 73ce168eead5d2627323f5944d2c7ee8629c85df602e3b432afdcb05ee29247a
3
+ metadata.gz: e89d0b87824703140e5d9182ade7936b22045bde791ba86d805dfbde9614f7b7
4
+ data.tar.gz: 2a3643dd2c6b3b837c3a4b1361651ca0a5b468336e038a38d1aaaa3bc659e151
5
5
  SHA512:
6
- metadata.gz: 26f409db40e28e6febeba959cc27a127d6caa531d66974792efc7f1e4cf7ee8d0ca1e21130d6c874937ed645b24929e44094fd351add876f5471c0f37bf4a28d
7
- data.tar.gz: 02d122fcc7346aac33f12cf470462bb283602d277cd2fc09c1cba40c4d597ccd4e65527572e7ebd523535c7fe92bcf948a99ead45f1f3f6dd7420ba95703d2b0
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,12 +1,15 @@
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
3
+ This a plugin that makes managing a table of
5
4
  global key, value pairs easy. Think of it like a global Hash stored in your database,
6
5
  that uses simple ActiveRecord like methods for manipulation. Keep track of any global
7
6
  setting that you dont want to hard code into your rails app. You can store any kind
8
7
  of object. Strings, numbers, arrays, or any object.
9
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
+
10
13
  ## Status
11
14
 
12
15
  [![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)
@@ -41,11 +44,23 @@ You will get `app/models/setting.rb`
41
44
 
42
45
  ```rb
43
46
  class Setting < RailsSettings::Base
44
- source Rails.root.join("config/app.yml")
45
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
+ }
46
59
  end
47
60
  ```
48
61
 
62
+ You must use `field` method to statement the setting keys, otherwice you can't use it.
63
+
49
64
  Now just put that migration in the database with:
50
65
 
51
66
  ```bash
@@ -57,154 +72,92 @@ rake db:migrate
57
72
  The syntax is easy. First, lets 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.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
+ }
65
131
  ```
66
132
 
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
133
  ### Caching flow:
183
134
 
184
135
  ```
185
- Setting.foo -> Check Cache -> Exist - Write Cache -> Return
186
- |
187
- Check DB -> Exist -> Write Cache -> Return
136
+ Setting.host -> Check Cache -> Exist - Get value of key for cache -> Return
188
137
  |
189
- Check Default -> Exist -> Write Cache -> Return
138
+ Fetch all key and values from DB -> Write Cache -> Get value of key for cache -> return
190
139
  |
191
- Return nil
140
+ Return default value or nil
192
141
  ```
193
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
+
194
147
  ## Change cache key
195
148
 
196
- When `config/app.yml` has changed, you may need change the cache prefix to expires caches.
149
+ Some times you may need to force update cache, now you can use `cache_prefix`
197
150
 
198
151
  ```ruby
199
152
  class Setting < RailsSettings::Base
200
- cache_prefix { 'you-prefix' }
153
+ cache_prefix { "you-prefix" }
201
154
  ...
202
155
  end
203
156
  ```
204
157
 
205
158
  -----
206
159
 
207
- ## How to create a list, form to manage Settings?
160
+ ## How to manage Settings in admin interface?
208
161
 
209
162
  If you want create an admin interface to editing the Settings, you can try methods in follow:
210
163
 
@@ -224,61 +177,57 @@ module Admin
224
177
  class SettingsController < ApplicationController
225
178
  before_action :get_setting, only: [:edit, :update]
226
179
 
227
- def index
228
- @settings = Setting.get_all
229
- end
230
-
231
- def edit
180
+ def show
232
181
  end
233
182
 
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
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?
241
187
  end
188
+ redirect_to admin_settings_path(notice: "Setting was successfully updated.")
242
189
  end
243
190
 
244
- def get_setting
245
- @setting = Setting.find_by(var: params[:id]) || Setting.new(var: params[:id])
246
- end
191
+
192
+ private
193
+ def setting_params
194
+ params.require(:setting).permit(:host, :user_limits, :admin_emails,
195
+ :captcha_enable, :notification_options)
196
+ end
247
197
  end
248
198
  end
249
199
  ```
250
200
 
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
201
+ app/views/admin/settings/show.html.erb
269
202
 
270
203
  ```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 %>
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>
275
228
  <% end %>
276
229
  ```
277
230
 
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
231
  ## Use case:
283
232
 
284
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rails/generators"
2
4
  require "rails/generators/migration"
3
5
 
@@ -27,7 +29,6 @@ module Settings
27
29
 
28
30
  def install_setting
29
31
  template "model.rb", File.join("app/models", class_path, "#{file_name}.rb")
30
- template "app.yml", File.join("config", "app.yml")
31
32
  migration_template "migration.rb", "db/migrate/create_settings.rb", migration_version: migration_version
32
33
  end
33
34
 
@@ -3,12 +3,10 @@ class CreateSettings < ActiveRecord::Migration<%= migration_version %>
3
3
  create_table :settings do |t|
4
4
  t.string :var, null: false
5
5
  t.text :value, null: true
6
- t.integer :thing_id, null: true
7
- t.string :thing_type, null: true, limit: 30
8
6
  t.timestamps
9
7
  end
10
8
 
11
- add_index :settings, %i(thing_type thing_id var), unique: true
9
+ add_index :settings, %i(var), unique: true
12
10
  end
13
11
 
14
12
  def self.down
@@ -1,7 +1,10 @@
1
1
  # RailsSettings Model
2
2
  class <%= class_name %> < RailsSettings::Base
3
- source Rails.root.join("config/app.yml")
3
+ cache_prefix { "v1" }
4
4
 
5
- # When config/app.yml has changed, you need change this prefix to v2, v3 ... to expires caches
6
- # cache_prefix { "v1" }
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
7
10
  end
@@ -1,44 +1,121 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RailsSettings
2
- class Base < Settings
3
- def rewrite_cache
4
- Rails.cache.write(cache_key, value)
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?
5
13
  end
6
14
 
7
- def expire_cache
8
- Rails.cache.delete(cache_key)
15
+ # set the value field, YAML encoded
16
+ def value=(new_value)
17
+ self[:value] = new_value.to_yaml
9
18
  end
10
19
 
11
- def cache_key
12
- self.class.cache_key(var, thing)
20
+ def expire_cache
21
+ Thread.current[:rails_settings_all_settings] = nil
22
+ Rails.cache.delete(self.class.cache_key)
13
23
  end
14
24
 
15
25
  class << self
26
+ def field(key, **opts)
27
+ _define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly])
28
+ end
29
+
16
30
  def cache_prefix(&block)
17
31
  @cache_prefix = block
18
32
  end
19
33
 
20
- def cache_key(var_name, scope_object)
21
- scope = ["rails_settings_cached"]
34
+ def cache_key
35
+ scope = ["rails-settings-cached"]
22
36
  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
37
  scope.join("/")
26
38
  end
27
39
 
28
- def [](key)
29
- return super(key) unless rails_initialized?
30
- val = Rails.cache.fetch(cache_key(key, @object)) do
31
- super(key)
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
32
77
  end
33
- val
34
- end
35
78
 
36
- # set a setting value by [] notation
37
- def []=(var_name, value)
38
- super
39
- Rails.cache.write(cache_key(var_name, @object), value)
40
- value
41
- end
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
42
119
  end
43
120
  end
44
121
  end
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RailsSettings
2
4
  class Railtie < Rails::Railtie
3
5
  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
+ RailsSettings::Base.after_commit :expire_cache, on: %i(create update destroy)
6
7
  end
7
8
  end
8
9
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RailsSettings
2
4
  class << self
3
5
  def version
4
- "0.7.2"
6
+ "2.0.0"
5
7
  end
6
8
  end
7
9
  end
@@ -1,8 +1,6 @@
1
- require_relative "rails-settings/settings"
1
+ # frozen_string_literal: true
2
+
2
3
  require_relative "rails-settings/base"
3
- require_relative "rails-settings/scoped_settings"
4
- require_relative "rails-settings/default"
5
- require_relative "rails-settings/extend"
6
4
  require_relative "rails-settings/railtie"
7
5
  require_relative "rails-settings/version"
8
6
 
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.7.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Lee
8
- - Squeegy
9
- - Georg Ledermann
10
- - 100hz
11
8
  autorequire:
12
9
  bindir: bin
13
10
  cert_chain: []
14
- date: 2018-10-08 00:00:00.000000000 Z
11
+ date: 2019-04-26 00:00:00.000000000 Z
15
12
  dependencies:
16
13
  - !ruby/object:Gem::Dependency
17
14
  name: rails
@@ -45,16 +42,16 @@ dependencies:
45
42
  name: rubocop
46
43
  requirement: !ruby/object:Gem::Requirement
47
44
  requirements:
48
- - - '='
45
+ - - ">="
49
46
  - !ruby/object:Gem::Version
50
- version: 0.46.0
47
+ version: '0'
51
48
  type: :development
52
49
  prerelease: false
53
50
  version_requirements: !ruby/object:Gem::Requirement
54
51
  requirements:
55
- - - '='
52
+ - - ">="
56
53
  - !ruby/object:Gem::Version
57
- version: 0.46.0
54
+ version: '0'
58
55
  - !ruby/object:Gem::Dependency
59
56
  name: simplecov
60
57
  requirement: !ruby/object:Gem::Requirement
@@ -70,7 +67,7 @@ dependencies:
70
67
  - !ruby/object:Gem::Version
71
68
  version: '0'
72
69
  - !ruby/object:Gem::Dependency
73
- name: rspec
70
+ name: minitest
74
71
  requirement: !ruby/object:Gem::Requirement
75
72
  requirements:
76
73
  - - ">="
@@ -108,18 +105,15 @@ executables: []
108
105
  extensions: []
109
106
  extra_rdoc_files: []
110
107
  files:
108
+ - MIT-LICENSE
111
109
  - README.md
110
+ - Rakefile
112
111
  - lib/generators/settings/install_generator.rb
113
- - lib/generators/settings/templates/app.yml
114
112
  - lib/generators/settings/templates/migration.rb
115
113
  - lib/generators/settings/templates/model.rb
116
114
  - lib/rails-settings-cached.rb
117
115
  - lib/rails-settings/base.rb
118
- - lib/rails-settings/default.rb
119
- - lib/rails-settings/extend.rb
120
116
  - lib/rails-settings/railtie.rb
121
- - lib/rails-settings/scoped_settings.rb
122
- - lib/rails-settings/settings.rb
123
117
  - lib/rails-settings/version.rb
124
118
  homepage: https://github.com/huacnlee/rails-settings-cached
125
119
  licenses: []
@@ -132,15 +126,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
126
  requirements:
133
127
  - - ">="
134
128
  - !ruby/object:Gem::Version
135
- version: '2.3'
129
+ version: '2.5'
136
130
  required_rubygems_version: !ruby/object:Gem::Requirement
137
131
  requirements:
138
132
  - - ">="
139
133
  - !ruby/object:Gem::Version
140
134
  version: '0'
141
135
  requirements: []
142
- rubyforge_project:
143
- rubygems_version: 2.7.6
136
+ rubygems_version: 3.0.1
144
137
  signing_key:
145
138
  specification_version: 4
146
139
  summary: Settings plugin for Rails that makes managing a table of global keys.
@@ -1,13 +0,0 @@
1
- # config/app.yml for rails-settings-cached
2
- defaults: &defaults
3
- foo: "Foo"
4
- bar: 123
5
-
6
- development:
7
- <<: *defaults
8
-
9
- test:
10
- <<: *defaults
11
-
12
- production:
13
- <<: *defaults
@@ -1,40 +0,0 @@
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
@@ -1,34 +0,0 @@
1
- module RailsSettings
2
- module Extend
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- scope :with_settings, lambda {
7
- joins("JOIN settings ON (settings.thing_id = #{table_name}.#{primary_key} AND
8
- settings.thing_type = '#{base_class.name}')")
9
- .select("DISTINCT #{table_name}.*")
10
- }
11
-
12
- scope :with_settings_for, lambda { |var|
13
- joins("JOIN settings ON (settings.thing_id = #{table_name}.#{primary_key} AND
14
- settings.thing_type = '#{base_class.name}') AND settings.var = '#{var}'")
15
- }
16
-
17
- scope :without_settings, lambda {
18
- joins("LEFT JOIN settings ON (settings.thing_id = #{table_name}.#{primary_key} AND
19
- settings.thing_type = '#{base_class.name}')")
20
- .where("settings.id IS NULL")
21
- }
22
-
23
- scope :without_settings_for, lambda { |var|
24
- where("settings.id IS NULL")
25
- .joins("LEFT JOIN settings ON (settings.thing_id = #{table_name}.#{primary_key} AND
26
- settings.thing_type = '#{base_class.name}') AND settings.var = '#{var}'")
27
- }
28
- end
29
-
30
- def settings
31
- ScopedSettings.for_thing(self)
32
- end
33
- end
34
- end
@@ -1,12 +0,0 @@
1
- module RailsSettings
2
- class ScopedSettings < Base
3
- def self.for_thing(object)
4
- @object = object
5
- self
6
- end
7
-
8
- def self.thing_scoped
9
- unscoped.where(thing_type: @object.class.base_class.to_s, thing_id: @object.id)
10
- end
11
- end
12
- end
@@ -1,120 +0,0 @@
1
- module RailsSettings
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
- return Default[var_name] unless rails_initialized?
65
-
66
- val = object(var_name)
67
- return val.value if val
68
- return Default[var_name] if Default.enabled?
69
- end
70
-
71
- # set a setting value by [] notation
72
- def []=(var_name, value)
73
- var_name = var_name.to_s
74
-
75
- record = object(var_name) || thing_scoped.new(var: var_name)
76
- record.value = value
77
- record.save!
78
-
79
- value
80
- end
81
-
82
- def merge!(var_name, hash_value)
83
- raise ArgumentError unless hash_value.is_a?(Hash)
84
-
85
- old_value = self[var_name] || {}
86
- raise TypeError, "Existing value is not a hash, can't merge!" unless old_value.is_a?(Hash)
87
-
88
- new_value = old_value.merge(hash_value)
89
- self[var_name] = new_value if new_value != old_value
90
-
91
- new_value
92
- end
93
-
94
- def object(var_name)
95
- return nil unless table_exists?
96
- thing_scoped.where(var: var_name.to_s).first
97
- end
98
-
99
- def thing_scoped
100
- unscoped.where("thing_type is NULL and thing_id is NULL")
101
- end
102
-
103
- def source(filename)
104
- Default.source(filename)
105
- end
106
-
107
- def rails_initialized?
108
- Rails.application && Rails.application.initialized?
109
- end
110
-
111
- private
112
-
113
- def default_settings(starting_with = nil)
114
- return {} unless Default.enabled?
115
- return Default.instance if starting_with.nil?
116
- Default.instance.select { |key, _| key.to_s.start_with?(starting_with) }
117
- end
118
- end
119
- end
120
- end