rails-settings-cached 0.4.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 6bd842dbc504791a77630162468aa6e478a995c2
4
- data.tar.gz: 5dcfb862ea79ee47eec0dd6316dfad8b3d1ff811
2
+ SHA256:
3
+ metadata.gz: e89d0b87824703140e5d9182ade7936b22045bde791ba86d805dfbde9614f7b7
4
+ data.tar.gz: 2a3643dd2c6b3b837c3a4b1361651ca0a5b468336e038a38d1aaaa3bc659e151
5
5
  SHA512:
6
- metadata.gz: cd476936667b371251f5fb6b66a3a1dabdf5e99b6808171ecfdd0baa38bca03df6e6ed9475ed7a488626795952076a87d42923b174a13da57e4e1d24bb7c5e95
7
- data.tar.gz: 8f093f58bf66a5939d57c6d412a7b9ce742b95f0de4d2f34ea1c0db53fc720df7aa23761964162b0a6d9ff1344630afa405ad9c348bc266a18c0a8ef4008d560
6
+ metadata.gz: e6b9209c170d1b5d34b62496533936c4e8598bc963fb5bd1fbb3a8c5b86424e6c7986fb300eb4aebc89ce7e13f86d083588bef06e93c5c6927b18ccf2465e5e6
7
+ data.tar.gz: 7b7b05d0794663008292b3630c99c160f8fc54cc0b9e8b958d46052cb63ce94f9eff4d012d06b2676551cfc805502d890e5313a887d3611bfb6fdbd0ffb2d3d9
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2006 Alex Wayne
2
+ Some additional features added 2009 by Georg Ledermann
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND
18
+ NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,179 +1,233 @@
1
- # Settings Gem
2
-
3
- This is improved from rails-settings, added caching for all settings.
4
- Settings is a plugin that makes managing a table of global key, value pairs easy.
5
- Think of it like a global Hash stored in you database, that uses simple ActiveRecord
6
- like methods for manipulation. Keep track of any global setting that you dont want
7
- to hard code into your rails app. You can store any kind of object. Strings, numbers,
8
- arrays, or any object. Ported to Rails 3!
9
-
10
- ## Status
11
-
12
- - [![Gem Version](https://badge.fury.io/rb/rails-settings-cached.png)](https://rubygems.org/gems/rails-settings-cached)
13
- - [![CI Status](https://api.travis-ci.org/huacnlee/rails-settings-cached.png)](http://travis-ci.org/huacnlee/rails-settings-cached)
14
-
15
- ## Setup
16
-
17
- Edit your Gemfile:
18
-
19
- ```ruby
20
- # Rails 4.1.x
21
- gem "rails-settings-cached", "0.4.1"
22
- # Rails 4+
23
- gem "rails-settings-cached", "0.3.1"
24
- # Rails 3.x
25
- gem "rails-settings-cached", "0.2.4"
26
- ```
27
-
28
- Generate your settings:
29
-
30
- ```bash
31
- $ rails g settings <settings_name>
32
- ```
33
-
34
- Note: If you migrating from gem `rails-settings` then make sure you have it in your model
35
-
36
- ```ruby
37
- class Settings < RailsSettings::CachedSettings
38
- ...
39
- end
40
- ```
41
-
42
- Now just put that migration in the database with:
43
-
44
- ```bash
45
- rake db:migrate
46
- ```
47
-
48
- ## Usage
49
-
50
- The syntax is easy. First, lets create some settings to keep track of:
51
-
52
- ```ruby
53
- Setting.admin_password = 'supersecret'
54
- Setting.date_format = '%m %d, %Y'
55
- Setting.cocktails = ['Martini', 'Screwdriver', 'White Russian']
56
- Setting.foo = 123
57
- Setting.credentials = { :username => 'tom', :password => 'secret' }
58
- ```
59
-
60
- Now lets read them back:
61
-
62
- ```ruby
63
- Setting.foo # returns 123
64
- ```
65
-
66
- Changing an existing setting is the same as creating a new setting:
67
-
68
- ```ruby
69
- Setting.foo = 'super duper bar'
70
- ```
71
-
72
- For changing an existing setting which is a Hash, you can merge new values with existing ones:
73
-
74
- ```ruby
75
- Setting.merge!(:credentials, :password => 'topsecret')
76
- Setting.credentials # returns { :username => 'tom', :password => 'topsecret' }
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
-
88
- ```ruby
89
- Setting.get_all
90
- # returns {'admin_password' => 'super_secret', 'date_format' => '%m %d, %Y'}
91
- ```
92
-
93
- 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 like this:
94
-
95
- ```ruby
96
- Setting['preferences.color'] = :blue
97
- Setting['preferences.size'] = :large
98
- Setting['license.key'] = 'ABC-DEF'
99
- Setting.get_all('preferences.')
100
- # returns { 'preferences.color' => :blue, 'preferences.size' => :large }
101
- ```
102
-
103
- Set defaults for certain settings of your app. This will cause the defined settings to return with the
104
- Specified value even if they are **not in the database**. Make a new file in `config/initializers/default_settings.rb`
105
- with the following:
106
-
107
- ```ruby
108
- Setting.defaults[:some_setting] = 'footastic'
109
- Setting.where(:var => "some_setting").count
110
- => 0
111
- Setting.some_setting
112
- => "footastic"
113
- ```
114
-
115
- Init defualt value in database, this has indifferent with `Setting.defaults[:some_setting]`, this will **save the value into database**:
116
-
117
- ```ruby
118
- Setting.save_default(:some_key, "123")
119
- Setting.where(:var => "some_key").count
120
- => 1
121
- Setting.some_key
122
- => "123"
123
- ```
124
-
125
- Settings may be bound to any existing ActiveRecord object. Define this association like this:
126
- Notice! is not do caching in this version.
127
-
128
- ```ruby
129
- class User < ActiveRecord::Base
130
- include RailsSettings::Extend
131
- end
132
- ```
133
-
134
- Then you can set/get a setting for a given user instance just by doing this:
135
-
136
- ```ruby
137
- user = User.find(123)
138
- user.settings.color = :red
139
- user.settings.color # returns :red
140
- user.settings.get_all # { "color" => :red }
141
- ```
142
-
143
- I you want to find users having or not having some settings, there are named scopes for this:
144
-
145
- ```ruby
146
- User.with_settings
147
- # => returns a scope of users having any setting
148
-
149
- User.with_settings_for('color')
150
- # => returns a scope of users having a 'color' setting
151
-
152
- User.without_settings
153
- # returns a scope of users having no setting at all (means user.settings.get_all == {})
154
-
155
- User.without_settings('color')
156
- # returns a scope of users having no 'color' setting (means user.settings.color == nil)
157
- ```
158
-
159
- -----
160
-
161
- ## How to create a list, form to manage Settings?
162
-
163
- If you want create an admin interface to editing the Settings, you can try methods in follow:
164
-
165
- ```ruby
166
- class SettingsController < ApplicationController
167
- def index
168
- # to get all items for render list
169
- @settings = Setting.unscoped
170
- end
171
-
172
- def edit
173
- @setting = Setting.unscoped.find(params[:id])
174
- end
175
- end
176
- ```
177
-
178
-
179
- That's all there is to it! Enjoy!
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
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "rails/generators/migration"
5
+
6
+ module Settings
7
+ class InstallGenerator < Rails::Generators::NamedBase
8
+ desc "Generate RailsSettings files."
9
+ include Rails::Generators::Migration
10
+
11
+ argument :name, type: :string, default: "setting"
12
+
13
+ source_root File.expand_path("../templates", __FILE__)
14
+
15
+ @@migrations = false
16
+
17
+ def self.next_migration_number(dirname) #:nodoc:
18
+ if ActiveRecord::Base.timestamped_migrations
19
+ if @@migrations
20
+ (current_migration_number(dirname) + 1)
21
+ else
22
+ @@migrations = true
23
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
24
+ end
25
+ else
26
+ format "%.3d", current_migration_number(dirname) + 1
27
+ end
28
+ end
29
+
30
+ def install_setting
31
+ template "model.rb", File.join("app/models", class_path, "#{file_name}.rb")
32
+ migration_template "migration.rb", "db/migrate/create_settings.rb", migration_version: migration_version
33
+ end
34
+
35
+ def rails5?
36
+ Rails.version.start_with? "5"
37
+ end
38
+
39
+ def migration_version
40
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if rails5?
41
+ end
42
+ end
43
+ end
@@ -1,14 +1,12 @@
1
- class CreateSettings < ActiveRecord::Migration
1
+ class CreateSettings < ActiveRecord::Migration<%= migration_version %>
2
2
  def self.up
3
3
  create_table :settings do |t|
4
- t.string :var, :null => false
5
- t.text :value, :null => true
6
- t.integer :thing_id, :null => true
7
- t.string :thing_type, :limit => 30, :null => true
4
+ t.string :var, null: false
5
+ t.text :value, null: true
8
6
  t.timestamps
9
7
  end
10
-
11
- add_index :settings, [ :thing_type, :thing_id, :var ], :unique => true
8
+
9
+ add_index :settings, %i(var), unique: true
12
10
  end
13
11
 
14
12
  def self.down
@@ -1,2 +1,10 @@
1
- class <%= class_name %> < RailsSettings::CachedSettings
1
+ # RailsSettings Model
2
+ class <%= class_name %> < RailsSettings::Base
3
+ cache_prefix { "v1" }
4
+
5
+ # Define your fields
6
+ # field :host, type: :string, default: "http://localhost:3000"
7
+ # field :default_locale, default: "en", type: :string
8
+ # field :confirmable_enable, default: "0", type: :boolean
9
+ # field :admin_emails, default: "admin@rubyonrails.org", type: :array
2
10
  end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSettings
4
+ class Base < ActiveRecord::Base
5
+ class SettingNotFound < RuntimeError; end
6
+
7
+ SEPARATOR_REGEXP = /[\s,]/
8
+ self.table_name = table_name_prefix + "settings"
9
+
10
+ # get the value field, YAML decoded
11
+ def value
12
+ YAML.load(self[:value]) if self[:value].present?
13
+ end
14
+
15
+ # set the value field, YAML encoded
16
+ def value=(new_value)
17
+ self[:value] = new_value.to_yaml
18
+ end
19
+
20
+ def expire_cache
21
+ Thread.current[:rails_settings_all_settings] = nil
22
+ Rails.cache.delete(self.class.cache_key)
23
+ end
24
+
25
+ class << self
26
+ def field(key, **opts)
27
+ _define_field(key, default: opts[:default], type: opts[:type], readonly: opts[:readonly])
28
+ end
29
+
30
+ def cache_prefix(&block)
31
+ @cache_prefix = block
32
+ end
33
+
34
+ def cache_key
35
+ scope = ["rails-settings-cached"]
36
+ scope << @cache_prefix.call if @cache_prefix
37
+ scope.join("/")
38
+ end
39
+
40
+ private
41
+ def _define_field(key, default: nil, type: :string, readonly: false)
42
+ self.class.define_method(key) do
43
+ val = self.send(:_value_of, key)
44
+ result = nil
45
+ if !val.nil?
46
+ result = val
47
+ else
48
+ result = default
49
+ result = default.call if default.is_a?(Proc)
50
+ end
51
+
52
+ result = self.send(:_covert_string_to_typeof_value, type, result)
53
+
54
+ result
55
+ end
56
+
57
+ unless readonly
58
+ self.class.define_method("#{key}=") do |value|
59
+ var_name = key.to_s
60
+
61
+ record = find_by(var: var_name) || new(var: var_name)
62
+ value = self.send(:_covert_string_to_typeof_value, type, value)
63
+
64
+ record.value = value
65
+ record.save!
66
+
67
+ value
68
+ end
69
+ end
70
+
71
+ if type == :boolean
72
+ self.class.define_method("#{key}?") do
73
+ val = self.send(:_value_of, key)
74
+ val == "true" || val == "1"
75
+ end
76
+ end
77
+ end
78
+
79
+ def _covert_string_to_typeof_value(type, value)
80
+ return value unless value.is_a?(String) || value.is_a?(Integer)
81
+
82
+ case type
83
+ when :boolean
84
+ return value == "true" || value == "1" || value == 1 || value == true
85
+ when :array
86
+ return value.split(SEPARATOR_REGEXP).reject { |str| str.empty? }
87
+ when :hash
88
+ value = YAML.load(value).to_hash rescue {}
89
+ value.deep_stringify_keys!
90
+ return value
91
+ when :integer
92
+ return value.to_i
93
+ else
94
+ value
95
+ end
96
+ end
97
+
98
+ def _value_of(var_name)
99
+ raise "#{self.table_name} does not exist." unless table_exists?
100
+
101
+ _all_settings[var_name.to_s]
102
+ end
103
+
104
+ def rails_initialized?
105
+ Rails.application && Rails.application.initialized?
106
+ end
107
+
108
+ def _all_settings
109
+ raise "You can use settings before Rails initialize." unless rails_initialized?
110
+ Thread.current[:rails_settings_all_settings] ||= begin
111
+ Rails.cache.fetch(self.cache_key, expires_in: 1.week) do
112
+ vars = unscoped.select("var, value")
113
+ result = {}
114
+ vars.each { |record| result[record.var] = record.value }
115
+ result.with_indifferent_access
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -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
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSettings
4
+ class << self
5
+ def version
6
+ "2.0.0"
7
+ end
8
+ end
9
+ end
@@ -1,4 +1,8 @@
1
- require "rails-settings/settings"
2
- require "rails-settings/scoped_settings"
3
- require "rails-settings/cached_settings"
4
- require "rails-settings/extend"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rails-settings/base"
4
+ require_relative "rails-settings/railtie"
5
+ require_relative "rails-settings/version"
6
+
7
+ module RailsSettings
8
+ end
metadata CHANGED
@@ -1,17 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-settings-cached
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Squeegy
8
- - Georg Ledermann
9
- - 100hz
10
7
  - Jason Lee
11
8
  autorequire:
12
9
  bindir: bin
13
10
  cert_chain: []
14
- date: 2014-05-12 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
@@ -19,29 +16,105 @@ dependencies:
19
16
  requirements:
20
17
  - - ">="
21
18
  - !ruby/object:Gem::Version
22
- version: 4.0.0
19
+ version: 4.2.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: 4.0.0
30
- description:
26
+ version: 4.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: codecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: "\n This is improved from rails-settings, added caching.\n Settings
98
+ plugin for Rails that makes managing a table of global key,\n value pairs easy.
99
+ Think of it like a global Hash stored in you database,\n that uses simple ActiveRecord
100
+ like methods for manipulation.\n\n Keep track of any global setting that you dont
101
+ want to hard code into your rails app.\n You can store any kind of object. Strings,
102
+ numbers, arrays, or any object.\n "
31
103
  email: huacnlee@gmail.com
32
104
  executables: []
33
105
  extensions: []
34
106
  extra_rdoc_files: []
35
107
  files:
108
+ - MIT-LICENSE
36
109
  - README.md
37
- - lib/generators/settings/settings_generator.rb
110
+ - Rakefile
111
+ - lib/generators/settings/install_generator.rb
38
112
  - lib/generators/settings/templates/migration.rb
39
113
  - lib/generators/settings/templates/model.rb
40
114
  - lib/rails-settings-cached.rb
41
- - lib/rails-settings/cached_settings.rb
42
- - lib/rails-settings/extend.rb
43
- - lib/rails-settings/scoped_settings.rb
44
- - lib/rails-settings/settings.rb
115
+ - lib/rails-settings/base.rb
116
+ - lib/rails-settings/railtie.rb
117
+ - lib/rails-settings/version.rb
45
118
  homepage: https://github.com/huacnlee/rails-settings-cached
46
119
  licenses: []
47
120
  metadata: {}
@@ -53,21 +126,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
53
126
  requirements:
54
127
  - - ">="
55
128
  - !ruby/object:Gem::Version
56
- version: '0'
129
+ version: '2.5'
57
130
  required_rubygems_version: !ruby/object:Gem::Requirement
58
131
  requirements:
59
132
  - - ">="
60
133
  - !ruby/object:Gem::Version
61
134
  version: '0'
62
135
  requirements: []
63
- rubyforge_project:
64
- rubygems_version: 2.2.2
136
+ rubygems_version: 3.0.1
65
137
  signing_key:
66
138
  specification_version: 4
67
- summary: This is imporved from rails-settings, added caching. Settings is a plugin
68
- that makes managing a table of global key, value pairs easy. Think of it like a
69
- global Hash stored in you database, that uses simple ActiveRecord like methods for
70
- manipulation. Keep track of any global setting that you dont want to hard code
71
- into your rails app. You can store any kind of object. Strings, numbers, arrays,
72
- or any object. Ported to Rails 3!
139
+ summary: Settings plugin for Rails that makes managing a table of global keys.
73
140
  test_files: []
@@ -1,30 +0,0 @@
1
- require 'rails/generators/migration'
2
-
3
- class SettingsGenerator < Rails::Generators::NamedBase
4
- include Rails::Generators::Migration
5
-
6
- argument :name, :type => :string, :default => "my_settings"
7
-
8
- source_root File.expand_path('../templates', __FILE__)
9
-
10
- @@migrations = false
11
-
12
- def self.next_migration_number(dirname) #:nodoc:
13
- if ActiveRecord::Base.timestamped_migrations
14
- if @@migrations
15
- (current_migration_number(dirname) + 1)
16
- else
17
- @@migrations = true
18
- Time.now.utc.strftime("%Y%m%d%H%M%S")
19
- end
20
- else
21
- "%.3d" % (current_migration_number(dirname) + 1)
22
- end
23
- end
24
-
25
- def settings
26
- #generate(:model, name, "--skip-migration")
27
- template "model.rb", File.join("app/models",class_path,"#{file_name}.rb"), :force => true
28
- migration_template "migration.rb", "db/migrate/create_settings.rb"
29
- end
30
- end
@@ -1,25 +0,0 @@
1
- module RailsSettings
2
- class CachedSettings < Settings
3
- after_update :rewrite_cache
4
- after_create :rewrite_cache
5
- def rewrite_cache
6
- Rails.cache.write("settings:#{self.var}", self.value)
7
- end
8
-
9
- after_destroy { |record| Rails.cache.delete("settings:#{record.var}") }
10
-
11
- def self.[](var_name)
12
- cache_key = "settings:#{var_name}"
13
- obj = Rails.cache.fetch(cache_key) {
14
- super(var_name)
15
- }
16
- obj == nil ? @@defaults[var_name.to_s] : obj
17
- end
18
-
19
- def self.save_default(key,value)
20
- if self.send(key) == nil
21
- self.send("#{key}=",value)
22
- end
23
- end
24
- end
25
- end
@@ -1,37 +0,0 @@
1
- module RailsSettings
2
- module Extend
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- scope :with_settings, -> {
7
- joins("JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
8
- settings.thing_type = '#{self.base_class.name}')")
9
- .select("DISTINCT #{self.table_name}.*")
10
- }
11
-
12
-
13
- scope :with_settings_for, ->(var) {
14
- joins("JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
15
- settings.thing_type = '#{self.base_class.name}') AND settings.var = '#{var}'")
16
- }
17
-
18
- scope :without_settings, -> {
19
- joins("LEFT JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND settings.thing_type = '#{self.base_class.name}')")
20
- .where("settings.id IS NULL")
21
- }
22
-
23
- scope :without_settings_for, ->(var) {
24
- where('settings.id IS NULL')
25
- .joins("LEFT JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
26
- settings.thing_type = '#{self.base_class.name}') AND settings.var = '#{var}'")
27
- }
28
-
29
- end
30
-
31
- def settings
32
- ScopedSettings.for_thing(self)
33
- end
34
- end
35
- end
36
-
37
-
@@ -1,13 +0,0 @@
1
- module RailsSettings
2
- class ScopedSettings < Settings
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
-
12
- end
13
- end
@@ -1,118 +0,0 @@
1
- module RailsSettings
2
- class Settings < ActiveRecord::Base
3
-
4
- self.table_name = table_name_prefix + 'settings'
5
-
6
- class SettingNotFound < RuntimeError; end
7
-
8
- cattr_accessor :defaults
9
- @@defaults = {}.with_indifferent_access
10
-
11
- # Support old plugin
12
- if defined?(SettingsDefaults::DEFAULTS)
13
- @@defaults = SettingsDefaults::DEFAULTS.with_indifferent_access
14
- end
15
-
16
- #get or set a variable with the variable as the called method
17
- def self.method_missing(method, *args)
18
- method_name = method.to_s
19
- super(method, *args)
20
- rescue NoMethodError
21
- #set a value for a variable
22
- if method_name =~ /=$/
23
- var_name = method_name.gsub('=', '')
24
- value = args.first
25
- self[var_name] = value
26
- #retrieve a value
27
- else
28
- self[method_name]
29
- end
30
- end
31
-
32
- #destroy the specified settings record
33
- def self.destroy(var_name)
34
- var_name = var_name.to_s
35
- obj = object(var_name)
36
- unless obj.nil?
37
- obj.destroy
38
- true
39
- else
40
- raise SettingNotFound, "Setting variable \"#{var_name}\" not found"
41
- end
42
- end
43
-
44
- #retrieve all settings as a hash (optionally starting with a given namespace)
45
- def self.get_all(starting_with = nil)
46
- vars = thing_scoped.select("var,value")
47
- if starting_with
48
- vars = vars.where("var LIKE '#{starting_with}%'")
49
- end
50
-
51
- result = {}
52
- vars.each do |record|
53
- result[record.var] = record.value
54
- end
55
- result.with_indifferent_access
56
- end
57
-
58
- def self.where(sql = nil)
59
- if sql
60
- vars = thing_scoped.where(sql)
61
- end
62
- vars
63
- end
64
-
65
- #get a setting value by [] notation
66
- def self.[](var_name)
67
- if var = object(var_name)
68
- var.value
69
- elsif @@defaults[var_name.to_s]
70
- @@defaults[var_name.to_s]
71
- else
72
- nil
73
- end
74
- end
75
-
76
- #set a setting value by [] notation
77
- def self.[]=(var_name, value)
78
- var_name = var_name.to_s
79
-
80
- record = object(var_name) || thing_scoped.new(:var => var_name)
81
- record.value = value
82
- record.save!
83
-
84
- value
85
- end
86
-
87
- def self.merge!(var_name, hash_value)
88
- raise ArgumentError unless hash_value.is_a?(Hash)
89
-
90
- old_value = self[var_name] || {}
91
- raise TypeError, "Existing value is not a hash, can't merge!" unless old_value.is_a?(Hash)
92
-
93
- new_value = old_value.merge(hash_value)
94
- self[var_name] = new_value if new_value != old_value
95
-
96
- new_value
97
- end
98
-
99
- def self.object(var_name)
100
- thing_scoped.where(:var => var_name.to_s).first
101
- end
102
-
103
- #get the value field, YAML decoded
104
- def value
105
- YAML::load(self[:value])
106
- end
107
-
108
- #set the value field, YAML encoded
109
- def value=(new_value)
110
- self[:value] = new_value.to_yaml
111
- end
112
-
113
- def self.thing_scoped
114
- unscoped.where("thing_type is NULL and thing_id is NULL")
115
- end
116
-
117
- end
118
- end