rails-settings-cached 0.4.1 → 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
- 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