Odczyt i zapis konfiguracyjnych plików yml

Napisałem klasę do zapisu i odczytu konfiguracji w plikach yml, wykorzystuje gem ya2yaml.

[code=ruby]class Configuration
attr_accessor :filename, :path

def initialize(filename)
@filename = filename
@path = “#{Rails.root}/config/#{filename}.yml”
end

def load()
raise “File doesn’t exist.” unless File.exist?(@path)
YAML::load(File.open(@path))
end

def dump(params)
raise “You can’t save database file.” if @filename.eql?(“database”)
mode = “a”
if File.exist?(@path)
mode = “w”
end
File.open(@path, mode) do |f|
f.write params.ya2yaml(:syck_compatible => true)
end
end
end[/code]
Jak sprawdzam kod w konsoli to jest wszystko ok, ale jak chcę wykonać metodę dump z poziomu strony internetowej to wyskakuje mi błąd:

undefined method `ya2yaml' for #<ActiveSupport::HashWithIndifferentAccess:0xaa67e6c>

Wykonuję następujące polecenia

obj = {'test' => 'value'} c = Configuration.new('app_test') c.dump(obj)

Czy w aplikacji internetowej masz dołączaną tą bibliotekę? (np. w Gemfile pod Rails 3.0, albo config/environment.rb pod 2.3 albo require ‘ya2yaml’)

w Gemfile wpisałem

gem 'ya2yaml'

Później wykonałem polecenie

bundle

Jak wpisuje

bundle list

to ten gem pojawia mi się na liście

Poniżej zamieszczam kod dwóch klas, które utworzyłem do prostego zarządania plikami konfiguracyjnymi:

[code=ruby]class Configuration
attr_accessor :filename, :path, :content

def initialize(filename)
@filename = filename
@path = “#{Rails.root}/config/#{filename}.yml”
end

def load()
raise “File doesn’t exist.” unless File.exist?(@path)
@content = YAML::load(File.open(@path))
return nil if @content.empty?
return self
end

def to_hash()
@content
end

def to_object()
ObjectIt.new(@content)
end

def dump(params)
raise “You can’t save database file.” if @filename.eql?(“database”)
mode = “a”
mode = “w” if File.exist?(@path)
File.open(@path, mode) do |f|
f.write params.ya2yaml
end
end
end[/code]

[code=ruby]class ObjectIt < ActiveResource::Base
def initialize(hash)
puts hash
hash.each do |k,v|
v = ObjectIt.new(v) if v.is_a?(Hash)
self.instance_variable_set("@#{k}", v) rescue raise “Bad key name”
self.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")})
self.class.send(:define_method, “#{k}=”, proc{|v| self.instance_variable_set("@#{k}", v)})
end
end

def save()
hash_to_return = {}
self.instance_variables.each do |v|
instance_variable_value = instance_variable_get(v)
if instance_variable_value.is_a?(ObjectIt)
hash_value = instance_variable_value.save
hash_to_return[v.to_s.gsub("@","")] = hash_value
else
hash_to_return[v.to_s.gsub("@","")] = instance_variable_value
end
end
return hash_to_return
end
end[/code]
Pierwsza klasa wczytuje plik konfiguracyjny a druga klasa zamienia hash na obiekt, w tedn sposób jak mamy plik:

system: web: ... git: ...
Do każdej opcji mozemy odwołać się w ten sposób

config = Configuration.new('app') data = config.load.to_object puts data.system.web...
Pewnie nie jest to optymalne, ale o coś takiego mi chodziło, tylko jeszcze uruchomić to z poziomu www.