I'm developing a model which holds configuration settings for server options. The number and type of server options change, and I need some input on the pros/cons of two ways of doing it. I'm doing this separate from the rails ActiveRecord database. All my database interactions are going to be manually with the file system.
First, having the model dynamically create attributes as needed for each server specified. (as long as this is possible... I've never done it before)
Second, creating a single Hash, which has Keys of the server options, and values of the server settings.
I think the second would be easier to implement, but I'm not sure if it is the right way to go? It seems to be cleaner to go with dynamic attributes.
Is there a rule of thumb to go with for this?
Made something for you.
Here is how it would work.
s = Settings.new(SettingsFileManager.new(some_file))
s.ip # returns whats in the file.
s.ip = 10.0.0.1 # overrides the new value.
I haven't written the way it interacts with the files yet so you'll have to write a proper SettingsFileManager.
If anything it should give you a good base to get started. But I wrote it primarily as a test to see what I know about ruby. Since it uses some semi-tricky stuff.
Hosted it on github too with some tests.
class Settings
attr_accessor :settings
def initialize(file_writer)
@file_writer = file_writer
read_settings_to_new_hash
end
def read_settings_to_new_hash
@settings = fabricate_hash
@settings.replace(@file_writer.read_keys)
end
def fabricate_hash
InterceptedHash.new( &hash_saved_proc )
end
def hash_saved_proc
Proc.new do |key, value|
@file_writer.write_key(key, value)
end
end
def method_missing(m, *args, &block)
if @settings.has_key?(m) || args[0]
if args[0]
@settings[m.to_s.sub("=","").to_sym] = args[0]
else
@settings[m]
end
else
raise "unknown setting"
end
end
end
# Not implemented. This should continue the logic to interact with whatever you want.
class SettingsFileManager
def initialize(file)
@file = file
end
# write the key and its value somewhere.
def write_key(key, value)
puts 'write_key', key, value
end
# should return hash of keys.
def read_keys
puts 'read_keys'
Hash.new
end
end
class InterceptedHash < Hash
def initialize(&block)
super
@block = block
end
def store(key, value)
super(key, value)
@block.call(key, value)
end
def []=(key, value)
store(key, value)
end
end