lib/taketo/constructs/base_construct.rb in taketo-0.0.4 vs lib/taketo/constructs/base_construct.rb in taketo-0.0.5
- old
+ new
@@ -1,23 +1,73 @@
require 'taketo/support'
module Taketo
+ class NodesNotDefinedError < StandardError; end
+
module Constructs
class BaseConstruct
attr_reader :name
+ ##
+ # Adds nodes collections to the construct
+ #
+ # Example:
+ #
+ # class Bar < BaseConstruct
+ # has_nodes :foos, :foo
+ # end
+ #
+ # bar = Bar.new
+ # bar.foos # => foos collection
+ # bar.append_foo(foo) # adds node the collection
+ # bar.find_foo(:foo_name) # find foo in foos collection by name
+ #
+ def self.has_nodes(name_plural, name_singular)
+ self.node_types << name_plural
+
+ define_method "append_#{name_singular}" do |object|
+ nodes(name_plural) << object
+ end
+
+ define_method "find_#{name_singular}" do |name|
+ nodes(name_plural).find_by_name(name)
+ end
+
+ define_method name_plural do
+ nodes(name_plural)
+ end
+ end
+
+ def self.node_types
+ @node_types ||= []
+ end
+
def initialize(name)
@name = name
+ @nodes = {}
end
- def find(scope, name)
- send("find_#{scope}", name) or
+ def find(singular_node_name, name)
+ send("find_#{singular_node_name}", name) or
if block_given?
yield
else
- raise KeyError, "#{scope.to_s.capitalize} #{name} not found for #{self.class.name} #{name}"
+ raise KeyError, "#{singular_node_name} #{name} not found for #{node_type} #{self.name}"
end
end
+
+ def nodes(name_plural)
+ unless self.class.node_types.include?(name_plural)
+ raise NodesNotDefinedError, "#{name_plural} not defined for #{node_type}"
+ end
+ @nodes[name_plural] ||= Taketo::Support::NamedNodesCollection.new
+ end
+
+ def node_type
+ demodulized = self.class.name.gsub(/.*::/, '')
+ demodulized.gsub(/([a-z])([A-Z])/, '\\1_\\2').downcase.to_sym
+ end
+
end
end
end