rails-settings-cached 0.4.1 → 0.7.1

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: 888a069815b6bab14f9f929eafed86726e25ee9a039b8e39fc5f502cf6ee2296
4
+ data.tar.gz: 483ceb459e33194b5dc530b84ac12e4946b1d572cef3e5809c3304f52c05c7b9
5
5
  SHA512:
6
- metadata.gz: cd476936667b371251f5fb6b66a3a1dabdf5e99b6808171ecfdd0baa38bca03df6e6ed9475ed7a488626795952076a87d42923b174a13da57e4e1d24bb7c5e95
7
- data.tar.gz: 8f093f58bf66a5939d57c6d412a7b9ce742b95f0de4d2f34ea1c0db53fc720df7aa23761964162b0a6d9ff1344630afa405ad9c348bc266a18c0a8ef4008d560
6
+ metadata.gz: 403951a85e14d29e651fe77bd5d9a1c64ff31dbac0760bca38f0cbc94aceca99a7ff3ba6ea88663d4f116f8216be8930c7311d4d44aae83c9809ca8c3f9ab0f9
7
+ data.tar.gz: 338908c1df4dc0b0068011881bd4d98206c0e977cf6c1cf5e646559fd06a2d4ddcccafc54be9b53e17eb8267e50f90df0c620f6866f35677277fb4d6a184cd36
data/README.md CHANGED
@@ -1,179 +1,284 @@
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 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://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"
20
+ ```
21
+
22
+ Generate your settings:
23
+
24
+ ```bash
25
+ $ rails g settings:install
26
+ ```
27
+
28
+ If you want custom model name:
29
+
30
+ ```bash
31
+ $ rails g settings:install
32
+ ```
33
+
34
+ Or use a custom name:
35
+
36
+ ```bash
37
+ $ rails g settings:install SiteConfig
38
+ ```
39
+
40
+ You will get `app/models/setting.rb`
41
+
42
+ ```rb
43
+ class Setting < RailsSettings::Base
44
+ source Rails.root.join("config/app.yml")
45
+ # cache_prefix { "v1" }
46
+ end
47
+ ```
48
+
49
+ Now just put that migration in the database with:
50
+
51
+ ```bash
52
+ rake db:migrate
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ The syntax is easy. First, lets create some settings to keep track of:
58
+
59
+ ```ruby
60
+ Setting.admin_password = 'supersecret'
61
+ Setting.date_format = '%m %d, %Y'
62
+ Setting.cocktails = ['Martini', 'Screwdriver', 'White Russian']
63
+ Setting.foo = 123
64
+ Setting.credentials = { :username => 'tom', :password => 'secret' }
65
+ ```
66
+
67
+ Now lets read them back:
68
+
69
+ ```ruby
70
+ Setting.foo # returns 123
71
+ ```
72
+
73
+ Changing an existing setting is the same as creating a new setting:
74
+
75
+ ```ruby
76
+ Setting.foo = 'super duper bar'
77
+ ```
78
+
79
+ Decide you dont want to track a particular setting anymore?
80
+
81
+ ```ruby
82
+ Setting.destroy :foo
83
+ Setting.foo # returns nil
84
+ ```
85
+
86
+ Want a list of all the settings?
87
+ ```ruby
88
+ Setting.get_all
89
+ ```
90
+
91
+ You need name spaces and want a list of settings for a give name space? Just choose your prefered named space delimiter and use `Setting.get_all` (`Settings.all` for # Rails 3.x and 4.0.x) like this:
92
+
93
+ ```ruby
94
+ Setting['preferences.color'] = :blue
95
+ Setting['preferences.size'] = :large
96
+ Setting['license.key'] = 'ABC-DEF'
97
+ # Rails 4.1.x
98
+ Setting.get_all('preferences.')
99
+ # Rails 3.x and 4.0.x
100
+ Setting.all('preferences.')
101
+ # returns { 'preferences.color' => :blue, 'preferences.size' => :large }
102
+ ```
103
+
104
+ ## Extend a model
105
+
106
+ Settings may be bound to any existing ActiveRecord object. Define this association like this:
107
+ Notice! is not do caching in this version.
108
+
109
+ ```ruby
110
+ class User < ActiveRecord::Base
111
+ include RailsSettings::Extend
112
+ end
113
+ ```
114
+
115
+ Then you can set/get a setting for a given user instance just by doing this:
116
+
117
+ ```ruby
118
+ user = User.find(123)
119
+ user.settings.color = :red
120
+ user.settings.color # returns :red
121
+ user.settings.get_all
122
+ # { "color" => :red }
123
+ ```
124
+
125
+ If you want to find users having or not having some settings, there are named scopes for this:
126
+
127
+ ```ruby
128
+ User.with_settings
129
+ # => returns a scope of users having any setting
130
+
131
+ User.with_settings_for('color')
132
+ # => returns a scope of users having a 'color' setting
133
+
134
+ User.without_settings
135
+ # returns a scope of users having no setting at all (means user.settings.get_all == {})
136
+
137
+ User.without_settings('color')
138
+ # returns a scope of users having no 'color' setting (means user.settings.color == nil)
139
+ ```
140
+
141
+ ## Default settings
142
+
143
+ Sometimes you may want define default settings.
144
+
145
+ RailsSettings has generate a config YAML file in:
146
+
147
+ ```yml
148
+ # config/app.yml
149
+ defaults: &defaults
150
+ github_token: "123456"
151
+ twitter_token: "<%= ENV["TWITTER_TOKEN"] %>"
152
+ foo:
153
+ bar: "Foo bar"
154
+
155
+ development:
156
+ <<: *defaults
157
+
158
+ test:
159
+ <<: *defaults
160
+
161
+ production:
162
+ <<: *defaults
163
+ ```
164
+
165
+ And you can use by `Setting` model:
166
+
167
+ ```
168
+ Setting.github_token
169
+ => "123456"
170
+ Setting.github_token = "654321"
171
+ # Save into database.
172
+ Setting.github_token
173
+ # Read from databae / caching.
174
+ => "654321"
175
+ Setting['foo.bar']
176
+ => 'Foo bar'
177
+ ```
178
+
179
+ NOTE: YAML setting it also under the cache scope, when you restart Rails application, cache will expire,
180
+ so when you want change default config, you need restart Rails application server.
181
+
182
+ ### Caching flow:
183
+
184
+ ```
185
+ Setting.foo -> Check Cache -> Exist - Write Cache -> Return
186
+ |
187
+ Check DB -> Exist -> Write Cache -> Return
188
+ |
189
+ Check Default -> Exist -> Write Cache -> Return
190
+ |
191
+ Return nil
192
+ ```
193
+
194
+ ## Change cache key
195
+
196
+ When `config/app.yml` has changed, you may need change the cache prefix to expires caches.
197
+
198
+ ```ruby
199
+ class Setting < RailsSettings::Base
200
+ cache_prefix { 'you-prefix' }
201
+ ...
202
+ end
203
+ ```
204
+
205
+ -----
206
+
207
+ ## How to create a list, form to manage Settings?
208
+
209
+ If you want create an admin interface to editing the Settings, you can try methods in follow:
210
+
211
+ config/routes.rb
212
+
213
+ ```rb
214
+ namespace :admin do
215
+ resources :settings
216
+ end
217
+ ```
218
+
219
+
220
+ app/controllers/admin/settings_controller.rb
221
+
222
+ ```rb
223
+ module Admin
224
+ class SettingsController < ApplicationController
225
+ before_action :get_setting, only: [:edit, :update]
226
+
227
+ def index
228
+ @settings = Setting.get_all
229
+ end
230
+
231
+ def edit
232
+ end
233
+
234
+ def update
235
+ if @setting.value != params[:setting][:value]
236
+ @setting.value = params[:setting][:value]
237
+ @setting.save
238
+ redirect_to admin_settings_path, notice: 'Setting has updated.'
239
+ else
240
+ redirect_to admin_settings_path
241
+ end
242
+ end
243
+
244
+ def get_setting
245
+ @setting = Setting.find_by(var: params[:id]) || Setting.new(var: params[:id])
246
+ end
247
+ end
248
+ end
249
+ ```
250
+
251
+ app/views/admin/settings/index.html.erb
252
+
253
+ ```erb
254
+ <table>
255
+ <tr>
256
+ <th>Key</th>
257
+ <th></th>
258
+ </tr>
259
+ <% @settings.each_key do |key| %>
260
+ <tr>
261
+ <td><%= key %></td>
262
+ <td><%= link_to 'edit', edit_admin_setting_path(key) %></td>
263
+ </tr>
264
+ <% end %>
265
+ </table>
266
+ ```
267
+
268
+ app/views/admin/settings/edit.html.erb
269
+
270
+ ```erb
271
+ <%= form_for(@setting, url: admin_setting_path(@setting.var), method: 'patch') do |f| %>
272
+ <label><%= @setting.var %></label>
273
+ <%= f.text_area :value, rows: 10 %>
274
+ <%= f.submit %>
275
+ <% end %>
276
+ ```
277
+
278
+ Also you may use [rails-settings-ui](https://github.com/accessd/rails-settings-ui) gem
279
+ for building ready to using interface with validations,
280
+ or [activeadmin_settings_cached](https://github.com/artofhuman/activeadmin_settings_cached) gem if you use [activeadmin](https://github.com/activeadmin/activeadmin).
281
+
282
+ ## Use case:
283
+
284
+ - [ruby-china/ruby-china](https://github.com/ruby-china/ruby-china)
@@ -0,0 +1,42 @@
1
+ require "rails/generators"
2
+ require "rails/generators/migration"
3
+
4
+ module Settings
5
+ class InstallGenerator < Rails::Generators::NamedBase
6
+ desc "Generate RailsSettings files."
7
+ include Rails::Generators::Migration
8
+
9
+ argument :name, type: :string, default: "setting"
10
+
11
+ source_root File.expand_path("../templates", __FILE__)
12
+
13
+ @@migrations = false
14
+
15
+ def self.next_migration_number(dirname) #:nodoc:
16
+ if ActiveRecord::Base.timestamped_migrations
17
+ if @@migrations
18
+ (current_migration_number(dirname) + 1)
19
+ else
20
+ @@migrations = true
21
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
22
+ end
23
+ else
24
+ format "%.3d", current_migration_number(dirname) + 1
25
+ end
26
+ end
27
+
28
+ def install_setting
29
+ template "model.rb", File.join("app/models", class_path, "#{file_name}.rb")
30
+ template "app.yml", File.join("config", "app.yml")
31
+ migration_template "migration.rb", "db/migrate/create_settings.rb", migration_version: migration_version
32
+ end
33
+
34
+ def rails5?
35
+ Rails.version.start_with? "5"
36
+ end
37
+
38
+ def migration_version
39
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if rails5?
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ # config/app.yml for rails-settings-cached
2
+ defaults: &defaults
3
+ foo: "Foo"
4
+ bar: 123
5
+
6
+ development:
7
+ <<: *defaults
8
+
9
+ test:
10
+ <<: *defaults
11
+
12
+ production:
13
+ <<: *defaults
@@ -1,14 +1,14 @@
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
6
+ t.integer :thing_id, null: true
7
+ t.string :thing_type, null: true, limit: 30
8
8
  t.timestamps
9
9
  end
10
-
11
- add_index :settings, [ :thing_type, :thing_id, :var ], :unique => true
10
+
11
+ add_index :settings, %i(thing_type thing_id var), unique: true
12
12
  end
13
13
 
14
14
  def self.down
@@ -1,2 +1,7 @@
1
- class <%= class_name %> < RailsSettings::CachedSettings
1
+ # RailsSettings Model
2
+ class <%= class_name %> < RailsSettings::Base
3
+ source Rails.root.join("config/app.yml")
4
+
5
+ # When config/app.yml has changed, you need change this prefix to v2, v3 ... to expires caches
6
+ # cache_prefix { "v1" }
2
7
  end
@@ -0,0 +1,44 @@
1
+ module RailsSettings
2
+ class Base < Settings
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.to_s
25
+ scope.join("/")
26
+ end
27
+
28
+ def [](key)
29
+ return super(key) unless rails_initialized?
30
+ val = Rails.cache.fetch(cache_key(key, @object)) do
31
+ super(key)
32
+ end
33
+ val
34
+ end
35
+
36
+ # set a setting value by [] notation
37
+ def []=(var_name, value)
38
+ super
39
+ Rails.cache.write(cache_key(var_name, @object), value)
40
+ value
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,40 @@
1
+ require "digest/md5"
2
+
3
+ module RailsSettings
4
+ class Default < ::Hash
5
+ class MissingKey < StandardError; end
6
+
7
+ class << self
8
+ def enabled?
9
+ source_path && File.exist?(source_path)
10
+ end
11
+
12
+ def source(value = nil)
13
+ @source ||= value
14
+ end
15
+
16
+ def source_path
17
+ @source || Rails.root.join("config/app.yml")
18
+ end
19
+
20
+ def [](key)
21
+ # foo.bar.dar Nested fetch value
22
+ return instance[key] if instance.key?(key)
23
+ keys = key.to_s.split(".")
24
+ instance.dig(*keys)
25
+ end
26
+
27
+ def instance
28
+ return @instance if defined? @instance
29
+ @instance = new
30
+ end
31
+ end
32
+
33
+ def initialize
34
+ content = open(self.class.source_path).read
35
+ hash = content.empty? ? {} : YAML.load(ERB.new(content).result).to_hash
36
+ hash = hash[Rails.env] || {}
37
+ replace hash
38
+ end
39
+ end
40
+ end
@@ -1,37 +1,34 @@
1
1
  module RailsSettings
2
2
  module Extend
3
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
4
 
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}'")
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}.*")
16
10
  }
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}'")
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
27
  }
28
-
29
28
  end
30
-
29
+
31
30
  def settings
32
31
  ScopedSettings.for_thing(self)
33
32
  end
34
33
  end
35
34
  end
36
-
37
-
@@ -0,0 +1,8 @@
1
+ module RailsSettings
2
+ class Railtie < Rails::Railtie
3
+ initializer "rails_settings.active_record.initialization" do
4
+ RailsSettings::Base.after_commit :rewrite_cache, on: %i(create update)
5
+ RailsSettings::Base.after_commit :expire_cache, on: %i(destroy)
6
+ end
7
+ end
8
+ end
@@ -1,13 +1,12 @@
1
1
  module RailsSettings
2
- class ScopedSettings < Settings
2
+ class ScopedSettings < Base
3
3
  def self.for_thing(object)
4
4
  @object = object
5
5
  self
6
6
  end
7
-
7
+
8
8
  def self.thing_scoped
9
- unscoped.where(:thing_type => @object.class.base_class.to_s, :thing_id => @object.id)
9
+ unscoped.where(thing_type: @object.class.base_class.to_s, thing_id: @object.id)
10
10
  end
11
-
12
11
  end
13
- end
12
+ end
@@ -1,118 +1,118 @@
1
1
  module RailsSettings
2
2
  class Settings < ActiveRecord::Base
3
-
4
- self.table_name = table_name_prefix + 'settings'
3
+ self.table_name = table_name_prefix + "settings"
5
4
 
6
5
  class SettingNotFound < RuntimeError; end
7
6
 
8
- cattr_accessor :defaults
9
- @@defaults = {}.with_indifferent_access
7
+ belongs_to :thing, polymorphic: true
10
8
 
11
- # Support old plugin
12
- if defined?(SettingsDefaults::DEFAULTS)
13
- @@defaults = SettingsDefaults::DEFAULTS.with_indifferent_access
9
+ # get the value field, YAML decoded
10
+ def value
11
+ YAML.load(self[:value]) if self[:value].present?
14
12
  end
15
13
 
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
14
+ # set the value field, YAML encoded
15
+ def value=(new_value)
16
+ self[:value] = new_value.to_yaml
30
17
  end
31
18
 
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?
19
+ class << self
20
+ # get or set a variable with the variable as the called method
21
+ # rubocop:disable Style/MethodMissing
22
+ def method_missing(method, *args)
23
+ method_name = method.to_s
24
+ super(method, *args)
25
+ rescue NoMethodError
26
+ # set a value for a variable
27
+ if method_name[-1] == "="
28
+ var_name = method_name.sub("=", "")
29
+ value = args.first
30
+ self[var_name] = value
31
+ else
32
+ # retrieve a value
33
+ self[method_name]
34
+ end
35
+ end
36
+
37
+ # destroy the specified settings record
38
+ def destroy(var_name)
39
+ var_name = var_name.to_s
40
+ obj = object(var_name)
41
+ raise SettingNotFound, "Setting variable \"#{var_name}\" not found" if obj.nil?
42
+
37
43
  obj.destroy
38
44
  true
39
- else
40
- raise SettingNotFound, "Setting variable \"#{var_name}\" not found"
41
45
  end
42
- end
43
46
 
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}%'")
47
+ # retrieve all settings as a hash (optionally starting with a given namespace)
48
+ def get_all(starting_with = nil)
49
+ vars = thing_scoped.select("var, value")
50
+ vars = vars.where("var LIKE '#{starting_with}%'") if starting_with
51
+ result = {}
52
+ vars.each { |record| result[record.var] = record.value }
53
+ result.reverse_merge!(default_settings(starting_with))
54
+ result.with_indifferent_access
49
55
  end
50
56
 
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)
57
+ def where(sql = nil)
58
+ vars = thing_scoped.where(sql) if sql
59
+ vars
61
60
  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
61
+
62
+ # get a setting value by [] notation
63
+ def [](var_name)
64
+ val = object(var_name)
65
+ return val.value if val
66
+ return Default[var_name] if Default.enabled?
73
67
  end
74
- end
75
68
 
76
- #set a setting value by [] notation
77
- def self.[]=(var_name, value)
78
- var_name = var_name.to_s
69
+ # set a setting value by [] notation
70
+ def []=(var_name, value)
71
+ var_name = var_name.to_s
79
72
 
80
- record = object(var_name) || thing_scoped.new(:var => var_name)
81
- record.value = value
82
- record.save!
73
+ record = object(var_name) || thing_scoped.new(var: var_name)
74
+ record.value = value
75
+ record.save!
83
76
 
84
- value
85
- end
77
+ value
78
+ end
86
79
 
87
- def self.merge!(var_name, hash_value)
88
- raise ArgumentError unless hash_value.is_a?(Hash)
80
+ def merge!(var_name, hash_value)
81
+ raise ArgumentError unless hash_value.is_a?(Hash)
89
82
 
90
- old_value = self[var_name] || {}
91
- raise TypeError, "Existing value is not a hash, can't merge!" unless old_value.is_a?(Hash)
83
+ old_value = self[var_name] || {}
84
+ raise TypeError, "Existing value is not a hash, can't merge!" unless old_value.is_a?(Hash)
92
85
 
93
- new_value = old_value.merge(hash_value)
94
- self[var_name] = new_value if new_value != old_value
86
+ new_value = old_value.merge(hash_value)
87
+ self[var_name] = new_value if new_value != old_value
95
88
 
96
- new_value
97
- end
89
+ new_value
90
+ end
98
91
 
99
- def self.object(var_name)
100
- thing_scoped.where(:var => var_name.to_s).first
101
- end
92
+ def object(var_name)
93
+ return nil unless table_exists?
94
+ thing_scoped.where(var: var_name.to_s).first
95
+ end
102
96
 
103
- #get the value field, YAML decoded
104
- def value
105
- YAML::load(self[:value])
106
- end
97
+ def thing_scoped
98
+ unscoped.where("thing_type is NULL and thing_id is NULL")
99
+ end
107
100
 
108
- #set the value field, YAML encoded
109
- def value=(new_value)
110
- self[:value] = new_value.to_yaml
111
- end
101
+ def source(filename)
102
+ Default.source(filename)
103
+ end
112
104
 
113
- def self.thing_scoped
114
- unscoped.where("thing_type is NULL and thing_id is NULL")
115
- end
105
+ def rails_initialized?
106
+ Rails.application && Rails.application.initialized?
107
+ end
108
+
109
+ private
116
110
 
111
+ def default_settings(starting_with = nil)
112
+ return {} unless Default.enabled?
113
+ return Default.instance if starting_with.nil?
114
+ Default.instance.select { |key, _| key.to_s.start_with?(starting_with) }
115
+ end
116
+ end
117
117
  end
118
118
  end
@@ -0,0 +1,7 @@
1
+ module RailsSettings
2
+ class << self
3
+ def version
4
+ "0.7.1"
5
+ end
6
+ end
7
+ end
@@ -1,4 +1,10 @@
1
- require "rails-settings/settings"
2
- require "rails-settings/scoped_settings"
3
- require "rails-settings/cached_settings"
4
- require "rails-settings/extend"
1
+ require_relative "rails-settings/settings"
2
+ require_relative "rails-settings/base"
3
+ require_relative "rails-settings/scoped_settings"
4
+ require_relative "rails-settings/default"
5
+ require_relative "rails-settings/extend"
6
+ require_relative "rails-settings/railtie"
7
+ require_relative "rails-settings/version"
8
+
9
+ module RailsSettings
10
+ end
metadata CHANGED
@@ -1,17 +1,17 @@
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: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
+ - Jason Lee
7
8
  - Squeegy
8
9
  - Georg Ledermann
9
10
  - 100hz
10
- - Jason Lee
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-05-12 00:00:00.000000000 Z
14
+ date: 2018-06-22 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rails
@@ -19,29 +19,108 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 4.0.0
22
+ version: 4.2.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 4.0.0
30
- description:
29
+ version: 4.2.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: sqlite3
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ - !ruby/object:Gem::Dependency
45
+ name: rubocop
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - '='
49
+ - !ruby/object:Gem::Version
50
+ version: 0.46.0
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - '='
56
+ - !ruby/object:Gem::Version
57
+ version: 0.46.0
58
+ - !ruby/object:Gem::Dependency
59
+ name: simplecov
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ - !ruby/object:Gem::Dependency
73
+ name: rspec
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ - !ruby/object:Gem::Dependency
87
+ name: codecov
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ description: "\n This is improved from rails-settings, added caching.\n Settings
101
+ plugin for Rails that makes managing a table of global key,\n value pairs easy.
102
+ Think of it like a global Hash stored in you database,\n that uses simple ActiveRecord
103
+ like methods for manipulation.\n\n Keep track of any global setting that you dont
104
+ want to hard code into your rails app.\n You can store any kind of object. Strings,
105
+ numbers, arrays, or any object.\n "
31
106
  email: huacnlee@gmail.com
32
107
  executables: []
33
108
  extensions: []
34
109
  extra_rdoc_files: []
35
110
  files:
36
111
  - README.md
37
- - lib/generators/settings/settings_generator.rb
112
+ - lib/generators/settings/install_generator.rb
113
+ - lib/generators/settings/templates/app.yml
38
114
  - lib/generators/settings/templates/migration.rb
39
115
  - lib/generators/settings/templates/model.rb
40
116
  - lib/rails-settings-cached.rb
41
- - lib/rails-settings/cached_settings.rb
117
+ - lib/rails-settings/base.rb
118
+ - lib/rails-settings/default.rb
42
119
  - lib/rails-settings/extend.rb
120
+ - lib/rails-settings/railtie.rb
43
121
  - lib/rails-settings/scoped_settings.rb
44
122
  - lib/rails-settings/settings.rb
123
+ - lib/rails-settings/version.rb
45
124
  homepage: https://github.com/huacnlee/rails-settings-cached
46
125
  licenses: []
47
126
  metadata: {}
@@ -53,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
53
132
  requirements:
54
133
  - - ">="
55
134
  - !ruby/object:Gem::Version
56
- version: '0'
135
+ version: '2.3'
57
136
  required_rubygems_version: !ruby/object:Gem::Requirement
58
137
  requirements:
59
138
  - - ">="
@@ -61,13 +140,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
140
  version: '0'
62
141
  requirements: []
63
142
  rubyforge_project:
64
- rubygems_version: 2.2.2
143
+ rubygems_version: 2.7.6
65
144
  signing_key:
66
145
  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!
146
+ summary: Settings plugin for Rails that makes managing a table of global keys.
73
147
  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