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?
preguntado el 09 de marzo de 12 a las 14:03
Do you know about the Store functionality in Rails?
Basically you could write something like this:
class Server < ActiveRecord::Base store :options end
You need to create a new migration as well with an options column and type text.
Now you can add and read values to the 'options' store like so:
server_instance.options[:ip] = '10.0.1.7' server_instance.options[:ip] # returns the IP.
You can also clean this up by adding an accessors option to the store call.
class Server < ActiveRecord::Base store :options, accessors: [ :ip, :port ] end
Now you can use ip & port as regular attributes.
server_instance.ip = '10.0.1.7' server_instance.ip # returns the IP.
Made something for you.
Así es como funcionaría.
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 if args @settings[m.to_s.sub("=","").to_sym] = args 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