Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added model-level settings #13

Merged
merged 7 commits into from

5 participants

Jim Ryan Sebastian Castro Mark Nadig Mike Hoffmeyer Georg Ledermann
Jim Ryan

I added the ability to store model-wide settings, like so:

User.settings.foo = 'bar'

Which are inherited by instances of that class:

User.find(123).settings.foo => 'bar'

Inheritance now looks like this: default -> model -> object

So, if the setting doesn't exist on the object or the model, you'll get the default, as expected:

Settings.defaults['some_default'] = 'foo'
User.settings.some_default => 'foo'
User.find(123).settings.some_default => 'foo'

Jim Ryan

Added a couple of other features that I had worked on previously on another rails-settings fork.

#settings= method to set settings in bulk by passing a hash

user.settings = { :foo => 'bar', :something => 'else' }
user.settings[:foo] # => 'bar'
user.settings[:something] # => 'else'

#all now returns defaults as well

Settings.defaults[:apples] = 'red'
Settings.defaults[:oranges] = 'orange'
user.settings[:apples] = 'green' # overriding a default
user.settings[:limes] = 'green'

user.settings.all # => { :oranges => 'orange', :apples => 'green', :limes => 'green' }
Jim Ryan

Just wanted to update this test to clarify that #settings= merges in the hash passed to it, it doesn't replace all settings with it.

Sebastian Castro

Amazing modification, just what I was looking for! Thx!

Jim Ryan

Thanks! Glad you like it!

Mark Nadig

Yeah, thanks Jim.

Mike Hoffmeyer

+1 for committing this pull. The hash merge is a much-needed feature!

Georg Ledermann ledermann merged commit 1b0057e into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
2  README.md
View
@@ -78,7 +78,7 @@ Decide you dont want to track a particular setting anymore?
Settings.foo
# => nil
-Want a list of all the settings?
+Want a list of all the settings (including defaults)?
Settings.all
# => { 'admin_password' => 'super_secret', 'date_format' => '%m %d, %Y' }
10 lib/rails-settings/active_record.rb
View
@@ -4,7 +4,15 @@ def self.has_settings
def settings
ScopedSettings.for_target(self)
end
-
+
+ def self.settings
+ ScopedSettings.for_target(self)
+ end
+
+ def settings=(hash)
+ hash.each { |k,v| settings[k] = v }
+ end
+
after_destroy { |user| user.settings.target_scoped.delete_all }
scope_method = ActiveRecord::VERSION::MAJOR < 3 ? :named_scope : :scope
4 lib/rails-settings/scoped_settings.rb
View
@@ -5,10 +5,10 @@ def self.for_target(target)
end
def self.target_id
- @target.id
+ @target.is_a?(Class) ? nil : @target.id
end
def self.target_type
- @target.class.base_class.to_s
+ @target.is_a?(Class) ? @target.name : @target.class.base_class.to_s
end
end
10 lib/rails-settings/settings.rb
View
@@ -50,7 +50,9 @@ def self.all(starting_with=nil)
vars.each do |record|
result[record.var] = record.value
end
- result.with_indifferent_access
+ defaults = @@defaults.select{ |k, v| k =~ /^#{starting_with}/ }
+ defaults = Hash[defaults] if defaults.is_a?(Array)
+ defaults.merge(result).with_indifferent_access
end
#get a setting value by [] notation
@@ -58,7 +60,11 @@ def self.[](var_name)
if var = target(var_name)
var.value
else
- @@defaults[var_name.to_s]
+ if target_id.nil?
+ @@defaults[var_name.to_s]
+ else
+ target_type.constantize.settings[var_name.to_s]
+ end
end
end
3  rails-settings.gemspec
View
@@ -19,7 +19,8 @@ Gem::Specification.new do |s|
s.require_paths = ['lib']
# specify any dependencies here; for example:
- # s.add_development_dependency "rspec"
+ s.add_development_dependency "rake"
+ s.add_development_dependency "sqlite3"
# s.add_runtime_dependency "rest-client"
s.add_dependency 'activerecord', '>= 2.3'
end
33 test/settings_test.rb
View
@@ -10,6 +10,7 @@ def setup
def teardown
Settings.delete_all
+ User.delete_all
end
def test_defaults
@@ -149,6 +150,38 @@ def test_false
assert_setting(nil, 'test3')
end
+ def test_class_level_settings
+ assert_equal User.settings.name, "ScopedSettings"
+ end
+
+ def test_object_inherits_class_settings_before_default
+ Settings.defaults['foo'] = 'default'
+ User.settings.foo = 'class'
+ user = User.create :name => 'Dwight'
+ assert_equal user.settings.foo, 'class'
+ end
+
+ def test_class_inherits_default_settings
+ Settings.defaults['foo'] = 'bar'
+ assert_equal User.settings.foo, 'bar'
+ end
+
+ def test_sets_settings_with_hash
+ user = User.create :name => 'Mr. Foo'
+ user.settings[:one] = 1
+ user.settings[:two] = 2
+ user.settings = { :two => 'two', :three => 3 }
+ assert_equal 1, user.settings[:one] # ensure existing settings remain intact
+ assert_equal 'two', user.settings[:two] # ensure settings are properly overwritten
+ assert_equal 3, user.settings[:three] # ensure new settings are created
+ end
+
+ def test_all_includes_defaults
+ Settings.defaults[:foo] = 'bar'
+ user = User.create :name => 'Mr. Foo'
+ assert_equal({ 'foo' => 'bar' }, user.settings.all)
+ end
+
private
def assert_setting(value, key, scope_target=nil)
key = key.to_sym
Something went wrong with that request. Please try again.