lib/cockpit/core/settings.rb in cockpit-0.1.1 vs lib/cockpit/core/settings.rb in cockpit-0.2.0
- old
+ new
@@ -1,146 +1,185 @@
module Cockpit
# settings have one direct definition and many child proxy
class Settings
+ include Global
+
class << self
- attr_accessor :definitions
-
- # Cockpit::Settings.define!(:name => "root", :scope => "default")
- def define!(*args, &block)
- setting = Cockpit::Settings.new(*args, &block)
- @root ||= setting
- setting
+ def specs
+ @specs ||= {}
end
- def store
- root.store
+ def global_settings
+ @global_settings ||= {}
end
- def store_type
- @store_type ||= :memory
+ def define!(options = {}, &block)
+ options = {:store => options.to_sym} unless options.is_a?(Hash)
+ options = configure(options)
+
+ unless options[:class] == NilClass
+ options[:class].send(:include, Cockpit::Store.support(options[:store]))
+ end
+
+ spec options[:name], options[:class], Cockpit::Settings::Spec.new(options, &block)
+
+ settings = Cockpit::Settings.new(options)
+
+ if options[:class] == NilClass
+ global_setting options[:name], options[:class], settings
+ end
+
+ settings
end
- def definitions
- @definitions ||= []
- end
-
- def definitions_for(name)
- definitions.detect do |i|
- i.name == name.to_s
+ def configure(options)
+ name = (options[:name] || "default").to_s
+ relationship = options[:class] || options[:for] || options[:class_name] || options[:record]
+ store = options[:store]
+
+ # class to include this in
+ clazz = case relationship
+ when Class
+ relationship
+ when Object
+ relationship.class
+ when String, Symbol
+ Object.const_get(relationship.to_s)
+ else
+ NilClass
end
+
+ # store to use in the include
+ unless store
+ if defined?(::ActiveRecord::Base) && clazz.ancestors.include?(::ActiveRecord::Base)
+ store = :active_record
+ else
+ store = :memory
+ end
+ end
+
+ options[:class] = clazz
+ options[:store] = store
+ options[:name] = name
+
+ options
end
- def definitions_for?(name)
- !definitions_for(name).blank?
+ def spec(name, clazz = NilClass, value = nil)
+ specs[clazz.to_s] ||= {}
+ specs[clazz.to_s][name.to_s] ||= value if value
+ specs[clazz.to_s][name.to_s]
end
- def root
- @root ||= Cockpit::Settings.new(:name => "root", :store => store_type, :scope => "default")
+ def global_setting(name, clazz = NilClass, value = nil)
+ global_settings[clazz.to_s] ||= {}
+ global_settings[clazz.to_s][name.to_s] = value if value
+ global_settings[clazz.to_s][name.to_s]
end
- def [](key)
- root[key]
+ def global
+ global_setting("default")
end
-
- def []=(key, value)
- root[key] = value
- end
-
- def clear
- root.clear
- end
- def default(key)
- root.default(key)
+ def find(name)
+ global_setting(name)
end
- def inspect
- "Cockpit::Settings root: #{root.inspect}"
+ def method_missing(method, *args, &block)
+ global.send(method, *args, &block)
end
end
- attr_accessor :name, :scope, :store, :record
+ attr_reader :name, :record, :store, :store_type, :record_type
- # Settings.new(:store => :memory, :record => @user, :definitions => Settings.definitions.first)
- def initialize(*args, &block)
- options = args.extract_options!
- options[:name] ||= "root"
- options[:store] ||= args.first
- options.each do |k, v|
- send("#{k}=", v)
- end
- raise ArgumentError.new("pass in a :store to Cockpit::Settings") if self.store.nil?
-
- args << options
-
- if definition = self.class.definitions_for(options[:name])
- definition.define!(*args, &block)
- else
- self.class.definitions << Cockpit::Definitions.new(*args, &block)
- end
+ def initialize(options = {}, &block)
+ options = self.class.configure(options)
+ @name = options[:name]
+ @record = options[:record]
+ @record_type = options[:class] || @record.class
+ @store_type = options[:store]
+ @store = Cockpit::Store.use(options)
end
- def store=(value)
- @store = Cockpit::Store.new(name, value, record).adapter
- end
-
def merge!(hash)
hash.each do |key, value|
self[key] = value
end
end
-
+
def keys
- definitions.keys
+ spec.keys
end
-
+
def [](key)
self.store[key.to_s] || default(key.to_s)
end
def []=(key, value)
- self.store[key.to_s] = value
+ with_callbacks(key, value) do |value|
+ self.store[key.to_s] = value
+ end
end
+ def with_callbacks(key, new_value, &block)
+ definition(key).with_callbacks(record, new_value, &block)
+ end
+
def clear
self.store.clear
end
def has_key?(key)
- !_definition(key).blank?
+ spec.has_key?(key)#!definition(key).blank?
end
def default(key)
- _definition(key).value
+ definition(key).value
end
def definition(key)
- _definition(key).dup
+ spec.definition(key)
end
def to_hash
keys.inject({}) do |hash, key|
hash[key] = self[key]
hash
end
end
- def roots
- @roots ||= keys.select { |key| key !~ /\./ }
+ def update(hash)
+ hash.each do |key, value|
+ self[key] = value
+ end
end
- protected
- def definitions
- @definitions ||= self.class.definitions_for(self.name)
+ def each(&block)
+ keys.each do |key|
+ case block.arity
+ when 1
+ yield(key)
+ when 2
+ yield(key, self[key])
+ end
+ end
end
- def _definition(key)
- definitions[key.to_s]
+ def roots
+ spec.roots
end
+ def spec
+ @spec ||= self.class.spec(self.name, self.record_type)
+ end
+
+ protected
+
def method_missing(method, *args, &block)
- if has_key?(method)
- definition(method)
+ if method.to_s =~ /(\w+)\?$/
+ has_key?($1)
+ elsif has_key?(method)
+ Cockpit::Scope.new(self, method, *args, &block)
else
super(method, *args, &block)
end
end
end