Almost in every web application, the administrator user need to setup some system parameters on the fly.
These parameter settings are different from the application configuration, which normally stored in the yml files under the config directory. Some of the developers incline to create a migration and store such properties into DB.
But for most of the simple situations, the YAML file just work fine. We only need to wrap it a little like a GlobalSetting class listed below.
So that you can save your params
got from controller directly like:
GlobalSetting.save param[:setting]
And retrieve them just by:
GlobalSetting[:TAX_RATE]
The setting hash you save can have more complex structure combined by arrays or other hashes,like:
GlobalSetting.save {:ACCOUNT => {:TAX_RATE => 0.2}}
Instead of using
GlobalSetting[:ACCOUNT] && GlobalSetting[:ACCOUNT][:TAX_RATE]
for avoiding the NoMethodError, we have a more DRY way:
GlobalSetting[:ACCOUNT, :TAX_RATE]
.
class GlobalSetting
cattr_accessor :file_path
self.file_path = File.join(RAILS_ROOT,'config','setting.yml')
def self.[](*keys)
keys.inject(setting){ |m,k| m[k] if m.is_a?(Array) || m.is_a?(Hash)}
end
def self.[]=(key,value)
setting[key] = value
end
def self.save(hash = nil)
hash = setting unless hash
File.open(file_path,'w+'){|f| f << hash.to_yaml}
@setting = load
end
def self.merge(hash)
setting.merge!(hash)
save
end
private
def self.setting
@setting ||= load
end
def self.load
File.file?(file_path) ? YAML.load_file(file_path) : {}
end
end
class GlobalSettingTest < ActiveSupport::TestCase
def setup
GlobalSetting.file_path = File.join(RAILS_ROOT,'tmp','test_setting.yml')
GlobalSetting.save :t1 => "v1",:t2 => "v2",:arr => ['a1','a2',3],
:h1 => {:nh => "nested" }
end
def test_load
assert_equal("v1", GlobalSetting[:t1])
assert_equal("v2", GlobalSetting[:t2])
assert_equal(3, GlobalSetting[:arr][2])
end
def test_update
assert_equal("v1", GlobalSetting[:t1])
GlobalSetting[:t1] ="c1"
GlobalSetting.save
assert_equal("c1", GlobalSetting[:t1])
end
def test_load_from_top
assert_equal("v1", GlobalSetting[][:t1])
end
def test_dig
assert_equal(3, GlobalSetting[:arr,2])
assert_equal("nested", GlobalSetting[:h1,:nh])
assert_nil(GlobalSetting[:t1,:foo,:bar])
assert_nil(GlobalSetting[:arr,2,:dd])
end
def test_merge
GlobalSetting.merge({:h1 => "new Value"})
assert_equal("v1", GlobalSetting[:t1])
assert_equal("new Value", GlobalSetting[:h1])
end
end
Comments