rails-settings-cached 0.5.6 → 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
- SHA1:
3
- metadata.gz: b57a0a5ecf132300eb30437cecef1d72ac4a6850
4
- data.tar.gz: 0819f21de6cb043141b20ff39ddd4c212aabd758
2
+ SHA256:
3
+ metadata.gz: e89d0b87824703140e5d9182ade7936b22045bde791ba86d805dfbde9614f7b7
4
+ data.tar.gz: 2a3643dd2c6b3b837c3a4b1361651ca0a5b468336e038a38d1aaaa3bc659e151
5
5
  SHA512:
6
- metadata.gz: b26625a6a49cc7413f18201e454374a6de07523705efd6eedd7d889aa464f2f07a057a541a277eba1fcfc1ad6cc791c4221ce6e84b35c2004cb37d86fdb661ad
7
- data.tar.gz: d2c7146010da954ef4b8010b5a3fe7bd92a9c6c100c389a8db3c834fd90429c64a648387f6d5885c414f13b407f4cde974b382d13c6a089cc5dc0373780ef7d2
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,202 +1,233 @@
1
- # Settings Gem
2
-
3
- This is improved from [rails-settings](https://github.com/ledermann/rails-settings),
4
- added caching for all settings. Settings is a plugin that makes managing a table of
5
- global key, value pairs easy. Think of it like a global Hash stored in your database,
6
- that uses simple ActiveRecord like methods for manipulation. Keep track of any global
7
- setting that you dont want to hard code into your rails app. You can store any kind
8
- of object. Strings, numbers, arrays, or any object.
9
-
10
- ## Status
11
-
12
- [![Gem Version](https://badge.fury.io/rb/rails-settings-cached.svg)](https://rubygems.org/gems/rails-settings-cached) [![CI Status](https://api.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)
13
-
14
- ## Setup
15
-
16
- Edit your Gemfile:
17
-
18
- ```ruby
19
- gem 'rails-settings-cached', "~> 0.5.6"
20
- ```
21
-
22
- Older Rails versions:
23
-
24
- ```rb
25
- # 4.1.x
26
- gem "rails-settings-cached", "~> 0.4.0"
27
- # 4.0.x
28
- gem "rails-settings-cached", "0.3.1"
29
- # 3.x
30
- gem "rails-settings-cached", "0.2.4"
31
- ```
32
-
33
- Generate your settings:
34
-
35
- ```bash
36
- $ rails g settings:install
37
- ```
38
-
39
- If you want custom model name:
40
-
41
- ```bash
42
- $ rails g settings:install MySetting
43
- ```
44
-
45
- Now just put that migration in the database with:
46
-
47
- ```bash
48
- rake db:migrate
49
- ```
50
-
51
- ## Usage
52
-
53
- The syntax is easy. First, lets create some settings to keep track of:
54
-
55
- ```ruby
56
- Setting.admin_password = 'supersecret'
57
- Setting.date_format = '%m %d, %Y'
58
- Setting.cocktails = ['Martini', 'Screwdriver', 'White Russian']
59
- Setting.foo = 123
60
- Setting.credentials = { :username => 'tom', :password => 'secret' }
61
- ```
62
-
63
- Now lets read them back:
64
-
65
- ```ruby
66
- Setting.foo # returns 123
67
- ```
68
-
69
- Changing an existing setting is the same as creating a new setting:
70
-
71
- ```ruby
72
- Setting.foo = 'super duper bar'
73
- ```
74
-
75
- For changing an existing setting which is a Hash, you can merge new values with existing ones:
76
-
77
- ```ruby
78
- Setting.merge!(:credentials, :password => 'topsecret')
79
- Setting.credentials # returns { :username => 'tom', :password => 'topsecret' }
80
- ```
81
-
82
- Decide you dont want to track a particular setting anymore?
83
-
84
- ```ruby
85
- Setting.destroy :foo
86
- Setting.foo # returns nil
87
- ```
88
-
89
- Want a list of all the settings?
90
- ```ruby
91
- # Rails 4.1.x
92
- Setting.get_all
93
- # Rails 3.x and 4.0.x
94
- Setting.all
95
- # returns {'admin_password' => 'super_secret', 'date_format' => '%m %d, %Y'}
96
- ```
97
-
98
- 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:
99
-
100
- ```ruby
101
- Setting['preferences.color'] = :blue
102
- Setting['preferences.size'] = :large
103
- Setting['license.key'] = 'ABC-DEF'
104
- # Rails 4.1.x
105
- Setting.get_all('preferences.')
106
- # Rails 3.x and 4.0.x
107
- Setting.all('preferences.')
108
- # returns { 'preferences.color' => :blue, 'preferences.size' => :large }
109
- ```
110
-
111
- Set defaults for certain settings of your app. This will cause the defined settings to return with the
112
- Specified value even if they are **not in the database**. Make a new file in `config/initializers/default_settings.rb`
113
- with the following:
114
-
115
- ```ruby
116
- Setting.defaults[:some_setting] = 'footastic'
117
- Setting.where(:var => "some_setting").count
118
- => 0
119
- Setting.some_setting
120
- => "footastic"
121
- ```
122
-
123
- Init default value in database, this has indifferent with `Setting.defaults[:some_setting]`, this will **save the value into database**:
124
-
125
- ```ruby
126
- Setting.save_default(:some_key, "123")
127
- Setting.where(:var => "some_key").count
128
- => 1
129
- Setting.some_key
130
- => "123"
131
- ```
132
-
133
- Settings may be bound to any existing ActiveRecord object. Define this association like this:
134
- Notice! is not do caching in this version.
135
-
136
- ```ruby
137
- class User < ActiveRecord::Base
138
- include RailsSettings::Extend
139
- end
140
- ```
141
-
142
- Then you can set/get a setting for a given user instance just by doing this:
143
-
144
- ```ruby
145
- user = User.find(123)
146
- user.settings.color = :red
147
- user.settings.color # returns :red
148
- # Rails 4.1.x
149
- user.settings.get_all
150
- # Rails 3.x and 4.0.x
151
- user.settings.all
152
- # { "color" => :red }
153
- ```
154
-
155
- If you want to find users having or not having some settings, there are named scopes for this:
156
-
157
- ```ruby
158
- User.with_settings
159
- # => returns a scope of users having any setting
160
-
161
- User.with_settings_for('color')
162
- # => returns a scope of users having a 'color' setting
163
-
164
- User.without_settings
165
- # returns a scope of users having no setting at all (means user.settings.get_all == {})
166
-
167
- User.without_settings('color')
168
- # returns a scope of users having no 'color' setting (means user.settings.color == nil)
169
- ```
170
-
171
- Settings maybe dynamically scoped. For example, if you're using [apartment gem](https://github.com/influitive/apartment) for multitenancy, you may not want tenants to share settings:
172
-
173
- ```ruby
174
- class Settings < RailsSettings::CachedSettings
175
- cache_prefix { Apartment::Tenant.current }
176
- ...
177
- end
178
- ```
179
-
180
- -----
181
-
182
- ## How to create a list, form to manage Settings?
183
-
184
- If you want create an admin interface to editing the Settings, you can try methods in follow:
185
-
186
- ```ruby
187
- class SettingsController < ApplicationController
188
- def index
189
- # to get all items for render list
190
- @settings = Setting.unscoped
191
- end
192
-
193
- def edit
194
- @setting = Setting.unscoped.find(params[:id])
195
- end
196
- end
197
- ```
198
-
199
-
200
- Also you may use [rails-settings-ui](https://github.com/accessd/rails-settings-ui) gem
201
- for building ready to using interface with validations.
202
-
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
+ [![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)
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
@@ -1,14 +1,16 @@
1
- require 'rails/generators'
2
- require 'rails/generators/migration'
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "rails/generators/migration"
3
5
 
4
6
  module Settings
5
7
  class InstallGenerator < Rails::Generators::NamedBase
6
8
  desc "Generate RailsSettings files."
7
9
  include Rails::Generators::Migration
8
10
 
9
- argument :name, type: :string, default: 'setting'
11
+ argument :name, type: :string, default: "setting"
10
12
 
11
- source_root File.expand_path('../templates', __FILE__)
13
+ source_root File.expand_path("../templates", __FILE__)
12
14
 
13
15
  @@migrations = false
14
16
 
@@ -18,16 +20,24 @@ module Settings
18
20
  (current_migration_number(dirname) + 1)
19
21
  else
20
22
  @@migrations = true
21
- Time.now.utc.strftime('%Y%m%d%H%M%S')
23
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
22
24
  end
23
25
  else
24
- format '%.3d', current_migration_number(dirname) + 1
26
+ format "%.3d", current_migration_number(dirname) + 1
25
27
  end
26
28
  end
27
29
 
28
30
  def install_setting
29
- template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb"), force: true
30
- migration_template 'migration.rb', 'db/migrate/create_settings.rb'
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?
31
41
  end
32
42
  end
33
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
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,3 +1,10 @@
1
1
  # RailsSettings Model
2
- class <%= class_name %> < RailsSettings::CachedSettings
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
3
10
  end
@@ -1,18 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RailsSettings
2
4
  class Base < ActiveRecord::Base
3
- self.table_name = table_name_prefix + 'settings'
4
-
5
5
  class SettingNotFound < RuntimeError; end
6
6
 
7
- cattr_accessor :defaults
8
- @@defaults = {}.with_indifferent_access
9
-
10
- belongs_to :thing, polymorphic: true
11
-
12
- # Support old plugin
13
- if defined?(SettingsDefaults::DEFAULTS)
14
- @@defaults = SettingsDefaults::DEFAULTS.with_indifferent_access
15
- end
7
+ SEPARATOR_REGEXP = /[\s,]/
8
+ self.table_name = table_name_prefix + "settings"
16
9
 
17
10
  # get the value field, YAML decoded
18
11
  def value
@@ -24,89 +17,105 @@ module RailsSettings
24
17
  self[:value] = new_value.to_yaml
25
18
  end
26
19
 
27
- class << self
28
- # get or set a variable with the variable as the called method
29
- def method_missing(method, *args)
30
- method_name = method.to_s
31
- super(method, *args)
32
- rescue NoMethodError
33
- # set a value for a variable
34
- if method_name[-1] == '='
35
- var_name = method_name.sub('=', '')
36
- value = args.first
37
- self[var_name] = value
38
- else
39
- # retrieve a value
40
- self[method_name]
41
- end
42
- end
43
-
44
- # destroy the specified settings record
45
- def destroy(var_name)
46
- var_name = var_name.to_s
47
- obj = object(var_name)
48
- raise SettingNotFound, "Setting variable \"#{var_name}\" not found" if obj.nil?
49
-
50
- obj.destroy
51
- true
52
- end
53
-
54
- # retrieve all settings as a hash (optionally starting with a given namespace)
55
- def get_all(starting_with = nil)
56
- vars = thing_scoped.select('var, value')
57
- vars = vars.where("var LIKE '#{starting_with}%'") if starting_with
58
-
59
- result = {}
60
- vars.each do |record|
61
- result[record.var] = record.value
62
- end
63
- default_keys = @@defaults.keys
64
- default_keys = default_keys.select {|k| k.start_with? starting_with } if starting_with
65
- result.merge! @@defaults.slice(*(default_keys - result.keys))
66
-
67
- result.with_indifferent_access
68
- end
20
+ def expire_cache
21
+ Thread.current[:rails_settings_all_settings] = nil
22
+ Rails.cache.delete(self.class.cache_key)
23
+ end
69
24
 
70
- def where(sql = nil)
71
- vars = thing_scoped.where(sql) if sql
72
- vars
25
+ class << self
26
+ def field(key, **opts)
27
+ _define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly])
73
28
  end
74
29
 
75
- # get a setting value by [] notation
76
- def [](var_name)
77
- object(var_name).try(:value) || @@defaults[var_name.to_s]
30
+ def cache_prefix(&block)
31
+ @cache_prefix = block
78
32
  end
79
33
 
80
- # set a setting value by [] notation
81
- def []=(var_name, value)
82
- var_name = var_name.to_s
83
-
84
- record = object(var_name) || thing_scoped.new(var: var_name)
85
- record.value = value
86
- record.save!
87
-
88
- value
34
+ def cache_key
35
+ scope = ["rails-settings-cached"]
36
+ scope << @cache_prefix.call if @cache_prefix
37
+ scope.join("/")
89
38
  end
90
39
 
91
- def merge!(var_name, hash_value)
92
- raise ArgumentError unless hash_value.is_a?(Hash)
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
93
78
 
94
- old_value = self[var_name] || {}
95
- raise TypeError, "Existing value is not a hash, can't merge!" unless old_value.is_a?(Hash)
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
96
97
 
97
- new_value = old_value.merge(hash_value)
98
- self[var_name] = new_value if new_value != old_value
98
+ def _value_of(var_name)
99
+ raise "#{self.table_name} does not exist." unless table_exists?
99
100
 
100
- new_value
101
- end
101
+ _all_settings[var_name.to_s]
102
+ end
102
103
 
103
- def object(var_name)
104
- thing_scoped.where(var: var_name.to_s).first
105
- end
104
+ def rails_initialized?
105
+ Rails.application && Rails.application.initialized?
106
+ end
106
107
 
107
- def thing_scoped
108
- unscoped.where('thing_type is NULL and thing_id is NULL')
109
- end
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
110
119
  end
111
120
  end
112
121
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSettings
4
+ class Railtie < Rails::Railtie
5
+ initializer "rails_settings.active_record.initialization" do
6
+ RailsSettings::Base.after_commit :expire_cache, on: %i(create update destroy)
7
+ end
8
+ end
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.5.6"
6
+ "2.0.0"
5
7
  end
6
8
  end
7
9
  end
@@ -1,15 +1,8 @@
1
- require_relative 'rails-settings/base'
2
- require_relative 'rails-settings/settings'
3
- require_relative 'rails-settings/cached_settings'
4
- require_relative 'rails-settings/scoped_settings'
5
- require_relative 'rails-settings/extend'
6
- require_relative 'rails-settings/version'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rails-settings/base"
4
+ require_relative "rails-settings/railtie"
5
+ require_relative "rails-settings/version"
7
6
 
8
7
  module RailsSettings
9
- class Railtie < Rails::Railtie
10
- initializer "rails_settings.active_record.initialization" do
11
- RailsSettings::CachedSettings.after_commit :rewrite_cache, on: %i(create update)
12
- RailsSettings::CachedSettings.after_commit :expire_cache, on: %i(destroy)
13
- end
14
- end
15
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.5.6
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: 2016-04-11 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
@@ -27,6 +24,76 @@ dependencies:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
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'
30
97
  description: "\n This is improved from rails-settings, added caching.\n Settings
31
98
  plugin for Rails that makes managing a table of global key,\n value pairs easy.
32
99
  Think of it like a global Hash stored in you database,\n that uses simple ActiveRecord
@@ -38,16 +105,15 @@ executables: []
38
105
  extensions: []
39
106
  extra_rdoc_files: []
40
107
  files:
108
+ - MIT-LICENSE
41
109
  - README.md
110
+ - Rakefile
42
111
  - lib/generators/settings/install_generator.rb
43
112
  - lib/generators/settings/templates/migration.rb
44
113
  - lib/generators/settings/templates/model.rb
45
114
  - lib/rails-settings-cached.rb
46
115
  - lib/rails-settings/base.rb
47
- - lib/rails-settings/cached_settings.rb
48
- - lib/rails-settings/extend.rb
49
- - lib/rails-settings/scoped_settings.rb
50
- - lib/rails-settings/settings.rb
116
+ - lib/rails-settings/railtie.rb
51
117
  - lib/rails-settings/version.rb
52
118
  homepage: https://github.com/huacnlee/rails-settings-cached
53
119
  licenses: []
@@ -60,15 +126,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
60
126
  requirements:
61
127
  - - ">="
62
128
  - !ruby/object:Gem::Version
63
- version: '2.1'
129
+ version: '2.5'
64
130
  required_rubygems_version: !ruby/object:Gem::Requirement
65
131
  requirements:
66
132
  - - ">="
67
133
  - !ruby/object:Gem::Version
68
134
  version: '0'
69
135
  requirements: []
70
- rubyforge_project:
71
- rubygems_version: 2.6.3
136
+ rubygems_version: 3.0.1
72
137
  signing_key:
73
138
  specification_version: 4
74
139
  summary: Settings plugin for Rails that makes managing a table of global keys.
@@ -1,54 +0,0 @@
1
- module RailsSettings
2
- class CachedSettings < Base
3
- def rewrite_cache
4
- Rails.cache.write(cache_key, value)
5
- end
6
-
7
- def expire_cache
8
- Rails.cache.delete(cache_key)
9
- end
10
-
11
- def cache_key
12
- self.class.cache_key(var, thing)
13
- end
14
-
15
- class << self
16
- def cache_prefix(&block)
17
- @cache_prefix = block
18
- end
19
-
20
- def cache_key(var_name, scope_object)
21
- scope = "rails_settings_cached:"
22
- scope << "#{@cache_prefix.call}:" if @cache_prefix
23
- scope << "#{scope_object.class.name}-#{scope_object.id}:" if scope_object
24
- scope << "#{var_name}"
25
- end
26
-
27
- def [](var_name)
28
- value = Rails.cache.fetch(cache_key(var_name, @object)) do
29
- super(var_name)
30
- end
31
-
32
- if value.nil?
33
- @@defaults[var_name.to_s] if value.nil?
34
- else
35
- value
36
- end
37
- end
38
-
39
- # set a setting value by [] notation
40
- def []=(var_name, value)
41
- super
42
-
43
- Rails.cache.write(cache_key(var_name, @object),value)
44
-
45
- value
46
- end
47
-
48
- def save_default(key, value)
49
- return false unless self[key].nil?
50
- self[key] = value
51
- end
52
- end
53
- end
54
- end
@@ -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 < CachedSettings
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,9 +0,0 @@
1
- module RailsSettings
2
- class Settings < Base
3
- def self.inherited(subclass)
4
- Kernel.warn 'DEPRECATION WARNING: RailsSettings::Settings is deprecated and it will removed in 0.6.0. ' <<
5
- 'Please use RailsSettings::Base instead.'
6
- super(subclass)
7
- end
8
- end
9
- end