rails-settings-cached 0.7.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eba484df56932a47956229096367746c7ffdeb979c61e2f9bcadbad09c0fd0a6
4
- data.tar.gz: 73ce168eead5d2627323f5944d2c7ee8629c85df602e3b432afdcb05ee29247a
3
+ metadata.gz: 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