我正在开发一个模型,其中包含服务器选项的配置设置。服务器选项的数量和类型发生了变化,我需要一些关于两种方式的优缺点的输入。我正在与 rails ActiveRecord 数据库分开执行此操作。我所有的数据库交互都将通过文件系统手动进行。
首先,让模型根据需要为每个指定的服务器动态创建属性。(只要这是可能的......我以前从未做过)
其次,创建单个哈希,其中包含服务器选项的键和服务器设置的值。
我认为第二个会更容易实施,但我不确定这是否是正确的方法?使用动态属性似乎更干净。
对此有经验法则吗?
我正在开发一个模型,其中包含服务器选项的配置设置。服务器选项的数量和类型发生了变化,我需要一些关于两种方式的优缺点的输入。我正在与 rails ActiveRecord 数据库分开执行此操作。我所有的数据库交互都将通过文件系统手动进行。
首先,让模型根据需要为每个指定的服务器动态创建属性。(只要这是可能的......我以前从未做过)
其次,创建单个哈希,其中包含服务器选项的键和服务器设置的值。
我认为第二个会更容易实施,但我不确定这是否是正确的方法?使用动态属性似乎更干净。
对此有经验法则吗?
你知道 Rails 中的 Store 功能吗?
http://api.rubyonrails.org/classes/ActiveRecord/Store.html
基本上你可以这样写:
class Server < ActiveRecord::Base
store :options
end
您还需要使用选项列创建新迁移并键入文本。
现在您可以像这样向“选项”存储添加和读取值:
server_instance.options[:ip] = '10.0.1.7'
server_instance.options[:ip] # returns the IP.
您还可以通过在 store 调用中添加访问器选项来清除它。
class Server < ActiveRecord::Base
store :options, accessors: [ :ip, :port ]
end
现在您可以使用 ip & port 作为常规属性。
server_instance.ip = '10.0.1.7'
server_instance.ip # returns the IP.
为你做了点什么。
这是它的工作原理。
s = Settings.new(SettingsFileManager.new(some_file))
s.ip # returns whats in the file.
s.ip = 10.0.0.1 # overrides the new value.
我还没有写出它与文件交互的方式,所以你必须写一个合适的 SettingsFileManager。
如果有的话,它应该为您提供良好的入门基础。但我写它主要是为了测试我对 ruby 的了解。因为它使用了一些半棘手的东西。
也通过一些测试将它托管在github上。
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