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